From 4e5d178f9367f4e51b387b7d4df1e8407b15fafc Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 13 Jul 2020 16:15:03 +0200
Subject: [PATCH 001/104] libcli:smb2: Do not leak ptext on error

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 libcli/smb/smb2_signing.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
index cc03607d789..4d430f56df5 100644
--- a/libcli/smb/smb2_signing.c
+++ b/libcli/smb/smb2_signing.c
@@ -520,6 +520,7 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key,
 
 		ctext = talloc_size(talloc_tos(), ctext_size);
 		if (ctext == NULL) {
+			TALLOC_FREE(ptext);
 			status = NT_STATUS_NO_MEMORY;
 			goto out;
 		}
-- 
2.29.2


From 1310c58c3b8b9c7fcb0c811a9ef24b3bbe8c16f1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 13 Jul 2020 17:23:37 +0200
Subject: [PATCH 002/104] libcli:smb2: Use talloc NULL context if we don't have
 a stackframe

If we execute this code from python we don't have a talloc stackframe
around and segfault with talloc_tos().

To fix the crash we use the NULL context as we take care for freeing the
memory as soon as possible.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 libcli/smb/smb2_signing.c | 30 ++++++++++++++++++++++++++----
 1 file changed, 26 insertions(+), 4 deletions(-)

diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c
index 4d430f56df5..6ece5f2e4d3 100644
--- a/libcli/smb/smb2_signing.c
+++ b/libcli/smb/smb2_signing.c
@@ -511,14 +511,25 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key,
 		uint8_t *ctext = NULL;
 		size_t len = 0;
 		int i;
+		TALLOC_CTX *tmp_ctx = NULL;
 
-		ptext = talloc_size(talloc_tos(), ptext_size);
+		/*
+		 * If we come from python bindings, we don't have a stackframe
+		 * around, so use the NULL context.
+		 *
+		 * This is fine as we make sure we free the memory.
+		 */
+		if (talloc_stackframe_exists()) {
+			tmp_ctx = talloc_tos();
+		}
+
+		ptext = talloc_size(tmp_ctx, ptext_size);
 		if (ptext == NULL) {
 			status = NT_STATUS_NO_MEMORY;
 			goto out;
 		}
 
-		ctext = talloc_size(talloc_tos(), ctext_size);
+		ctext = talloc_size(tmp_ctx, ctext_size);
 		if (ctext == NULL) {
 			TALLOC_FREE(ptext);
 			status = NT_STATUS_NO_MEMORY;
@@ -710,16 +721,27 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key,
 		uint8_t *ptext = NULL;
 		size_t len = 0;
 		int i;
+		TALLOC_CTX *tmp_ctx = NULL;
+
+		/*
+		 * If we come from python bindings, we don't have a stackframe
+		 * around, so use the NULL context.
+		 *
+		 * This is fine as we make sure we free the memory.
+		 */
+		if (talloc_stackframe_exists()) {
+			tmp_ctx = talloc_tos();
+		}
 
 		/* GnuTLS doesn't have a iovec API for decryption yet */
 
-		ptext = talloc_size(talloc_tos(), ptext_size);
+		ptext = talloc_size(tmp_ctx, ptext_size);
 		if (ptext == NULL) {
 			status = NT_STATUS_NO_MEMORY;
 			goto out;
 		}
 
-		ctext = talloc_size(talloc_tos(), ctext_size);
+		ctext = talloc_size(tmp_ctx, ctext_size);
 		if (ctext == NULL) {
 			TALLOC_FREE(ptext);
 			status = NT_STATUS_NO_MEMORY;
-- 
2.29.2


From ff15d93d1009a23428b9c11090836624255924cd Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Wed, 6 Nov 2019 17:37:45 +0100
Subject: [PATCH 003/104] auth:creds: Introduce CRED_SMB_CONF

We have several places where we check '> CRED_UNINITIALISED',
so we better don't use CRED_UNINITIALISED for values from
our smb.conf.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
 auth/credentials/credentials.c    | 6 +++---
 auth/credentials/credentials.h    | 1 +
 auth/credentials/pycredentials.c  | 1 +
 python/samba/tests/credentials.py | 4 ++--
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 81f9dbb9eb3..80a31b248ae 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -902,12 +902,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred,
 	if (lpcfg_parm_is_cmdline(lp_ctx, "workgroup")) {
 		cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_SPECIFIED);
 	} else {
-		cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_UNINITIALISED);
+		cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_SMB_CONF);
 	}
 	if (lpcfg_parm_is_cmdline(lp_ctx, "netbios name")) {
 		cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SPECIFIED);
 	} else {
-		cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_UNINITIALISED);
+		cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SMB_CONF);
 	}
 	if (realm != NULL && strlen(realm) == 0) {
 		realm = NULL;
@@ -915,7 +915,7 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred,
 	if (lpcfg_parm_is_cmdline(lp_ctx, "realm")) {
 		cli_credentials_set_realm(cred, realm, CRED_SPECIFIED);
 	} else {
-		cli_credentials_set_realm(cred, realm, CRED_UNINITIALISED);
+		cli_credentials_set_realm(cred, realm, CRED_SMB_CONF);
 	}
 
 	sep = lpcfg_winbind_separator(lp_ctx);
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 9fe6a82b1ea..7154c2a008c 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -42,6 +42,7 @@ struct db_context;
 /* In order of priority */
 enum credentials_obtained { 
 	CRED_UNINITIALISED = 0,  /* We don't even have a guess yet */
+	CRED_SMB_CONF,           /* Current value should be used, which comes from smb.conf */
 	CRED_CALLBACK, 		 /* Callback should be used to obtain value */
 	CRED_GUESS_ENV,	         /* Current value should be used, which was guessed */
 	CRED_GUESS_FILE,	 /* A guess from a file (or file pointed at in env variable) */
diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index a5d0f9e051c..68edc282741 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -1275,6 +1275,7 @@ MODULE_INIT_FUNC(credentials)
 		return NULL;
 
 	PyModule_AddObject(m, "UNINITIALISED", PyLong_FromLong(CRED_UNINITIALISED));
+	PyModule_AddObject(m, "SMB_CONF", PyLong_FromLong(CRED_SMB_CONF));
 	PyModule_AddObject(m, "CALLBACK", PyLong_FromLong(CRED_CALLBACK));
 	PyModule_AddObject(m, "GUESS_ENV", PyLong_FromLong(CRED_GUESS_ENV));
 	PyModule_AddObject(m, "GUESS_FILE", PyLong_FromLong(CRED_GUESS_FILE));
diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py
index d2a81506de3..6454ac9ff7c 100644
--- a/python/samba/tests/credentials.py
+++ b/python/samba/tests/credentials.py
@@ -332,7 +332,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir):
         os.environ["USER"] = "env_user"
         creds.guess(lp)
         realm = "realm.example.com"
-        creds.set_realm(realm, credentials.UNINITIALISED)
+        creds.set_realm(realm, credentials.SMB_CONF)
         creds.parse_string("user")
         self.assertEqual(creds.get_username(), "user")
         self.assertEqual(creds.get_domain(), lp.get("workgroup").upper())
@@ -360,7 +360,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir):
         os.environ["USER"] = "env_user"
         creds.guess(lp)
         realm = "realm.example.com"
-        creds.set_realm(realm, credentials.UNINITIALISED)
+        creds.set_realm(realm, credentials.SMB_CONF)
         self.assertEqual(creds.get_username(), "env_user")
         self.assertEqual(creds.get_domain(), lp.get("workgroup").upper())
         self.assertEqual(creds.get_realm(), realm.upper())
-- 
2.29.2


From cc5e70efc8b9f45054d7e57002f59ac38c4c687f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 10 Oct 2019 14:18:23 +0200
Subject: [PATCH 004/104] param: Add 'server smb encrypt' parameter

And this also makes 'smb encrypt' a synonym of that.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 .../smbdotconf/security/serversmbencrypt.xml  | 241 ++++++++++++++++++
 docs-xml/smbdotconf/security/smbencrypt.xml   | 241 +-----------------
 source3/param/loadparm.c                      |   2 +-
 source3/smbd/service.c                        |   4 +-
 source3/smbd/smb2_negprot.c                   |   2 +-
 source3/smbd/smb2_sesssetup.c                 |   4 +-
 source3/smbd/smb2_tcon.c                      |   4 +-
 source3/smbd/trans2.c                         |   2 +-
 8 files changed, 257 insertions(+), 243 deletions(-)
 create mode 100644 docs-xml/smbdotconf/security/serversmbencrypt.xml

diff --git a/docs-xml/smbdotconf/security/serversmbencrypt.xml b/docs-xml/smbdotconf/security/serversmbencrypt.xml
new file mode 100644
index 00000000000..714aacbf1ca
--- /dev/null
+++ b/docs-xml/smbdotconf/security/serversmbencrypt.xml
@@ -0,0 +1,241 @@
+<samba:parameter name="server smb encrypt"
+		 context="S"
+		 type="enum"
+		 enumlist="enum_smb_signing_vals"
+		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+	<para>
+	This parameter controls whether a remote client is allowed or required
+	to use SMB encryption. It has different effects depending on whether
+	the connection uses SMB1 or SMB2 and newer:
+	</para>
+
+	<itemizedlist>
+	<listitem>
+		<para>
+		If the connection uses SMB1, then this option controls the use
+		of a Samba-specific extension to the SMB protocol introduced in
+		Samba 3.2 that makes use of the Unix extensions.
+		</para>
+	</listitem>
+
+	<listitem>
+		<para>
+		If the connection uses SMB2 or newer, then this option controls
+		the use of the SMB-level encryption that is supported in SMB
+		version 3.0 and above and available in Windows 8 and newer.
+		</para>
+	</listitem>
+	</itemizedlist>
+
+	<para>
+		This parameter can be set globally and on a per-share bases.
+		Possible values are
+
+		<emphasis>off</emphasis>,
+		<emphasis>if_required</emphasis>,
+		<emphasis>desired</emphasis>,
+		and
+		<emphasis>required</emphasis>.
+		A special value is <emphasis>default</emphasis> which is
+		the implicit default setting of <emphasis>if_required</emphasis>.
+	</para>
+
+	<variablelist>
+		<varlistentry>
+		<term><emphasis>Effects for SMB1</emphasis></term>
+		<listitem>
+		<para>
+		The Samba-specific encryption of SMB1 connections is an
+		extension to the SMB protocol negotiated as part of the UNIX
+		extensions.  SMB encryption uses the GSSAPI (SSPI on Windows)
+		ability to encrypt and sign every request/response in a SMB
+		protocol stream. When enabled it provides a secure method of
+		SMB/CIFS communication, similar to an ssh protected session, but
+		using SMB/CIFS authentication to negotiate encryption and
+		signing keys. Currently this is only supported smbclient of by
+		Samba 3.2 and newer, and hopefully soon Linux CIFSFS and MacOS/X
+		clients. Windows clients do not support this feature.
+		</para>
+
+		<para>This may be set on a per-share
+		basis, but clients may chose to encrypt the entire session, not
+		just traffic to a specific share. If this is set to mandatory
+		then all traffic to a share <emphasis>must</emphasis>
+		be encrypted once the connection has been made to the share.
+		The server would return "access denied" to all non-encrypted
+		requests on such a share. Selecting encrypted traffic reduces
+		throughput as smaller packet sizes must be used (no huge UNIX
+		style read/writes allowed) as well as the overhead of encrypting
+		and signing all the data.
+		</para>
+
+		<para>
+		If SMB encryption is selected, Windows style SMB signing (see
+		the <smbconfoption name="server signing"/> option) is no longer
+		necessary, as the GSSAPI flags use select both signing and
+		sealing of the data.
+		</para>
+
+		<para>
+		When set to auto or default, SMB encryption is offered, but not
+		enforced.  When set to mandatory, SMB encryption is required and
+		if set to disabled, SMB encryption can not be negotiated.
+		</para>
+		</listitem>
+		</varlistentry>
+
+		<varlistentry>
+		<term><emphasis>Effects for SMB2 and newer</emphasis></term>
+		<listitem>
+		<para>
+		Native SMB transport encryption is available in SMB version 3.0
+		or newer. It is only offered by Samba if
+		<emphasis>server max protocol</emphasis> is set to
+		<emphasis>SMB3</emphasis> or newer.
+		Clients supporting this type of encryption include
+		Windows 8 and newer,
+		Windows server 2012 and newer,
+		and smbclient of Samba 4.1 and newer.
+		</para>
+
+		<para>
+		The protocol implementation offers various options:
+		</para>
+
+		<itemizedlist>
+			<listitem>
+			<para>
+			The capability to perform SMB encryption can be
+			negotiated during protocol negotiation.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Data encryption can be enabled globally. In that case,
+			an encryption-capable connection will have all traffic
+			in all its sessions encrypted. In particular all share
+			connections will be encrypted.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Data encryption can also be enabled per share if not
+			enabled globally. For an encryption-capable connection,
+			all connections to an encryption-enabled share will be
+			encrypted.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Encryption can be enforced. This means that session
+			setups will be denied on non-encryption-capable
+			connections if data encryption has been enabled
+			globally. And tree connections will be denied for
+			non-encryption capable connections to shares with data
+			encryption enabled.
+			</para>
+			</listitem>
+		</itemizedlist>
+
+		<para>
+		These features can be controlled with settings of
+		<emphasis>server smb encrypt</emphasis> as follows:
+		</para>
+
+		<itemizedlist>
+			<listitem>
+			<para>
+			Leaving it as default, explicitly setting
+			<emphasis>default</emphasis>, or setting it to
+			<emphasis>if_required</emphasis> globally will enable
+			negotiation of encryption but will not turn on
+			data encryption globally or per share.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>desired</emphasis> globally
+			will enable negotiation and will turn on data encryption
+			on sessions and share connections for those clients
+			that support it.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>required</emphasis> globally
+			will enable negotiation and turn on data encryption
+			on sessions and share connections. Clients that do
+			not support encryption will be denied access to the
+			server.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>off</emphasis> globally will
+			completely disable the encryption feature for all
+			connections. Setting <parameter>server smb encrypt =
+			required</parameter> for individual shares (while it's
+			globally off) will deny access to this shares for all
+			clients.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>desired</emphasis> on a share
+			will turn on data encryption for this share for clients
+			that support encryption if negotiation has been
+			enabled globally.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>required</emphasis> on a share
+			will enforce data encryption for this share if
+			negotiation has been enabled globally. I.e. clients that
+			do not support encryption will be denied access to the
+			share.
+			</para>
+			<para>
+			Note that this allows per-share enforcing to be
+			controlled in Samba differently from Windows:
+			In Windows, <emphasis>RejectUnencryptedAccess</emphasis>
+			is a global setting, and if it is set, all shares with
+			data encryption turned on
+			are automatically enforcing encryption. In order to
+			achieve the same effect in Samba, one
+			has to globally set <emphasis>server smb encrypt</emphasis> to
+			<emphasis>if_required</emphasis>, and then set all shares
+			that should be encrypted to
+			<emphasis>required</emphasis>.
+			Additionally, it is possible in Samba to have some
+			shares with encryption <emphasis>required</emphasis>
+			and some other shares with encryption only
+			<emphasis>desired</emphasis>, which is not possible in
+			Windows.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>off</emphasis> or
+			<emphasis>if_required</emphasis> for a share has
+			no effect.
+			</para>
+			</listitem>
+		</itemizedlist>
+		</listitem>
+		</varlistentry>
+	</variablelist>
+</description>
+
+<value type="default">default</value>
+</samba:parameter>
diff --git a/docs-xml/smbdotconf/security/smbencrypt.xml b/docs-xml/smbdotconf/security/smbencrypt.xml
index 32a22cb58f5..798e616b765 100644
--- a/docs-xml/smbdotconf/security/smbencrypt.xml
+++ b/docs-xml/smbdotconf/security/smbencrypt.xml
@@ -1,241 +1,14 @@
 <samba:parameter name="smb encrypt"
-                 context="S"
-                 type="enum"
-                 enumlist="enum_smb_signing_vals"
-                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+		 context="S"
+		 type="enum"
+		 enumlist="enum_smb_signing_vals"
+		 function="server_smb_encrypt"
+		 synonym="1"
+		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
 	<para>
-	This parameter controls whether a remote client is allowed or required
-	to use SMB encryption. It has different effects depending on whether
-	the connection uses SMB1 or SMB2 and newer:
+		This is a synonym for <smbconfoption name="server smb encrypt"/>.
 	</para>
-
-	<itemizedlist>
-	<listitem>
-		<para>
-		If the connection uses SMB1, then this option controls the use
-		of a Samba-specific extension to the SMB protocol introduced in
-		Samba 3.2 that makes use of the Unix extensions.
-		</para>
-	</listitem>
-
-	<listitem>
-		<para>
-		If the connection uses SMB2 or newer, then this option controls
-		the use of the SMB-level encryption that is supported in SMB
-		version 3.0 and above and available in Windows 8 and newer.
-		</para>
-	</listitem>
-	</itemizedlist>
-
-	<para>
-		This parameter can be set globally and on a per-share bases.
-		Possible values are
-		<emphasis>off</emphasis> (or <emphasis>disabled</emphasis>),
-		<emphasis>enabled</emphasis> (or <emphasis>auto</emphasis>, or
-		<emphasis>if_required</emphasis>),
-		<emphasis>desired</emphasis>,
-		and
-		<emphasis>required</emphasis>
-		(or <emphasis>mandatory</emphasis>).
-		A special value is <emphasis>default</emphasis> which is
-		the implicit default setting of <emphasis>enabled</emphasis>.
-	</para>
-
-	<variablelist>
-		<varlistentry>
-		<term><emphasis>Effects for SMB1</emphasis></term>
-		<listitem>
-		<para>
-		The Samba-specific encryption of SMB1 connections is an
-		extension to the SMB protocol negotiated as part of the UNIX
-		extensions.  SMB encryption uses the GSSAPI (SSPI on Windows)
-		ability to encrypt and sign every request/response in a SMB
-		protocol stream. When enabled it provides a secure method of
-		SMB/CIFS communication, similar to an ssh protected session, but
-		using SMB/CIFS authentication to negotiate encryption and
-		signing keys. Currently this is only supported smbclient of by
-		Samba 3.2 and newer, and hopefully soon Linux CIFSFS and MacOS/X
-		clients. Windows clients do not support this feature.
-		</para>
-
-		<para>This may be set on a per-share
-		basis, but clients may chose to encrypt the entire session, not
-		just traffic to a specific share. If this is set to mandatory
-		then all traffic to a share <emphasis>must</emphasis>
-		be encrypted once the connection has been made to the share.
-		The server would return "access denied" to all non-encrypted
-		requests on such a share. Selecting encrypted traffic reduces
-		throughput as smaller packet sizes must be used (no huge UNIX
-		style read/writes allowed) as well as the overhead of encrypting
-		and signing all the data.
-		</para>
-
-		<para>
-		If SMB encryption is selected, Windows style SMB signing (see
-		the <smbconfoption name="server signing"/> option) is no longer
-		necessary, as the GSSAPI flags use select both signing and
-		sealing of the data.
-		</para>
-
-		<para>
-		When set to auto or default, SMB encryption is offered, but not
-		enforced.  When set to mandatory, SMB encryption is required and
-		if set to disabled, SMB encryption can not be negotiated.
-		</para>
-		</listitem>
-		</varlistentry>
-
-		<varlistentry>
-		<term><emphasis>Effects for SMB2</emphasis></term>
-		<listitem>
-		<para>
-		Native SMB transport encryption is available in SMB version 3.0
-		or newer. It is only offered by Samba if
-		<emphasis>server max protocol</emphasis> is set to
-		<emphasis>SMB3</emphasis> or newer.
-		Clients supporting this type of encryption include
-		Windows 8 and newer,
-		Windows server 2012 and newer,
-		and smbclient of Samba 4.1 and newer.
-		</para>
-
-		<para>
-		The protocol implementation offers various options:
-		</para>
-
-		<itemizedlist>
-			<listitem>
-			<para>
-			The capability to perform SMB encryption can be
-			negotiated during protocol negotiation.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Data encryption can be enabled globally. In that case,
-			an encryption-capable connection will have all traffic
-			in all its sessions encrypted. In particular all share
-			connections will be encrypted.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Data encryption can also be enabled per share if not
-			enabled globally. For an encryption-capable connection,
-			all connections to an encryption-enabled share will be
-			encrypted.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Encryption can be enforced. This means that session
-			setups will be denied on non-encryption-capable
-			connections if data encryption has been enabled
-			globally. And tree connections will be denied for
-			non-encryption capable connections to shares with data
-			encryption enabled.
-			</para>
-			</listitem>
-		</itemizedlist>
-
-		<para>
-		These features can be controlled with settings of
-		<emphasis>smb encrypt</emphasis> as follows:
-		</para>
-
-		<itemizedlist>
-			<listitem>
-			<para>
-			Leaving it as default, explicitly setting
-			<emphasis>default</emphasis>, or setting it to
-			<emphasis>enabled</emphasis> globally will enable
-			negotiation of encryption but will not turn on
-			data encryption globally or per share.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Setting it to <emphasis>desired</emphasis> globally
-			will enable negotiation and will turn on data encryption
-			on sessions and share connections for those clients
-			that support it.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Setting it to <emphasis>required</emphasis> globally
-			will enable negotiation and turn on data encryption
-			on sessions and share connections. Clients that do
-			not support encryption will be denied access to the
-			server.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Setting it to <emphasis>off</emphasis> globally will
-			completely disable the encryption feature for all
-			connections. Setting <parameter>smb encrypt =
-			required</parameter> for individual shares (while it's
-			globally off) will deny access to this shares for all
-			clients.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Setting it to <emphasis>desired</emphasis> on a share
-			will turn on data encryption for this share for clients
-			that support encryption if negotiation has been
-			enabled globally.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Setting it to <emphasis>required</emphasis> on a share
-			will enforce data encryption for this share if
-			negotiation has been enabled globally. I.e. clients that
-			do not support encryption will be denied access to the
-			share.
-			</para>
-			<para>
-			Note that this allows per-share enforcing to be
-			controlled in Samba differently from Windows:
-			In Windows, <emphasis>RejectUnencryptedAccess</emphasis>
-			is a global setting, and if it is set, all shares with
-			data encryption turned on
-			are automatically enforcing encryption. In order to
-			achieve the same effect in Samba, one
-			has to globally set <emphasis>smb encrypt</emphasis> to
-			<emphasis>enabled</emphasis>, and then set all shares
-			that should be encrypted to
-			<emphasis>required</emphasis>.
-			Additionally, it is possible in Samba to have some
-			shares with encryption <emphasis>required</emphasis>
-			and some other shares with encryption only
-			<emphasis>desired</emphasis>, which is not possible in
-			Windows.
-			</para>
-			</listitem>
-
-			<listitem>
-			<para>
-			Setting it to <emphasis>off</emphasis> or
-			<emphasis>enabled</emphasis> for a share has
-			no effect.
-			</para>
-			</listitem>
-		</itemizedlist>
-		</listitem>
-		</varlistentry>
-	</variablelist>
 </description>
 
 <value type="default">default</value>
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index a3abaa2ec67..c0070b716a5 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -241,7 +241,7 @@ static const struct loadparm_service _sDefault =
 	.aio_write_size = 1,
 	.map_readonly = MAP_READONLY_NO,
 	.directory_name_cache_size = 100,
-	.smb_encrypt = SMB_SIGNING_DEFAULT,
+	.server_smb_encrypt = SMB_SIGNING_DEFAULT,
 	.kernel_share_modes = true,
 	.durable_handles = true,
 	.check_parent_directory_delete_on_close = false,
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index ed38121f292..a263c33b7e2 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -567,9 +567,9 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 	conn->case_preserve = lp_preserve_case(snum);
 	conn->short_case_preserve = lp_short_preserve_case(snum);
 
-	conn->encrypt_level = lp_smb_encrypt(snum);
+	conn->encrypt_level = lp_server_smb_encrypt(snum);
 	if (conn->encrypt_level > SMB_SIGNING_OFF) {
-		if (lp_smb_encrypt(-1) == SMB_SIGNING_OFF) {
+		if (lp_server_smb_encrypt(-1) == SMB_SIGNING_OFF) {
 			if (conn->encrypt_level == SMB_SIGNING_REQUIRED) {
 				DBG_ERR("Service [%s] requires encryption, but "
 					"it is disabled globally!\n",
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 4071f42b5e0..674942b71de 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -335,7 +335,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 	}
 
 	if ((protocol >= PROTOCOL_SMB2_24) &&
-	    (lp_smb_encrypt(-1) != SMB_SIGNING_OFF) &&
+	    (lp_server_smb_encrypt(-1) != SMB_SIGNING_OFF) &&
 	    (in_capabilities & SMB2_CAP_ENCRYPTION)) {
 		capabilities |= SMB2_CAP_ENCRYPTION;
 	}
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 2b6b3a820d4..8957411e167 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -292,12 +292,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 		x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
 	}
 
-	if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
+	if ((lp_server_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
 	    (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
 		x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
 	}
 
-	if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
+	if (lp_server_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
 		x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
 			SMBXSRV_ENCRYPTION_DESIRED;
 	}
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 76112d04889..0dd3c653b4b 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -302,13 +302,13 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 		TALLOC_FREE(proxy);
 	}
 
-	if ((lp_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) &&
+	if ((lp_server_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) &&
 	    (conn->smb2.server.cipher != 0))
 	{
 		encryption_desired = true;
 	}
 
-	if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) {
+	if (lp_server_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) {
 		encryption_desired = true;
 		encryption_required = true;
 	}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 7acde285a90..b745e0906b1 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4484,7 +4484,7 @@ static void call_trans2setfsinfo(connection_struct *conn,
 					return;
 				}
 
-				if (lp_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) {
+				if (lp_server_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) {
 					reply_nterror(
 						req,
 						NT_STATUS_NOT_SUPPORTED);
-- 
2.29.2


From d78374a9e26428a48b3c6a2aa1d4280751620fb9 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 10:04:19 +0200
Subject: [PATCH 005/104] param: Create and use enum_smb_encryption_vals

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 .../smbdotconf/security/serversmbencrypt.xml  |  2 +-
 docs-xml/smbdotconf/security/smbencrypt.xml   |  2 +-
 lib/param/param_table.c                       | 23 +++++++++++++++++++
 libcli/smb/smb_constants.h                    |  9 ++++++++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/docs-xml/smbdotconf/security/serversmbencrypt.xml b/docs-xml/smbdotconf/security/serversmbencrypt.xml
index 714aacbf1ca..5f38b46419e 100644
--- a/docs-xml/smbdotconf/security/serversmbencrypt.xml
+++ b/docs-xml/smbdotconf/security/serversmbencrypt.xml
@@ -1,7 +1,7 @@
 <samba:parameter name="server smb encrypt"
 		 context="S"
 		 type="enum"
-		 enumlist="enum_smb_signing_vals"
+		 enumlist="enum_smb_encryption_vals"
 		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
 	<para>
diff --git a/docs-xml/smbdotconf/security/smbencrypt.xml b/docs-xml/smbdotconf/security/smbencrypt.xml
index 798e616b765..60271200c0a 100644
--- a/docs-xml/smbdotconf/security/smbencrypt.xml
+++ b/docs-xml/smbdotconf/security/smbencrypt.xml
@@ -1,7 +1,7 @@
 <samba:parameter name="smb encrypt"
 		 context="S"
 		 type="enum"
-		 enumlist="enum_smb_signing_vals"
+		 enumlist="enum_smb_encryption_vals"
 		 function="server_smb_encrypt"
 		 synonym="1"
 		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index 47b85de1f87..e2f737279dc 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -138,6 +138,29 @@ static const struct enum_list enum_smb_signing_vals[] = {
 	{-1, NULL}
 };
 
+static const struct enum_list enum_smb_encryption_vals[] = {
+	{SMB_ENCRYPTION_DEFAULT, "default"},
+	{SMB_ENCRYPTION_OFF, "No"},
+	{SMB_ENCRYPTION_OFF, "False"},
+	{SMB_ENCRYPTION_OFF, "0"},
+	{SMB_ENCRYPTION_OFF, "Off"},
+	{SMB_ENCRYPTION_OFF, "disabled"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "if_required"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "Yes"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "True"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "1"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "On"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "enabled"},
+	{SMB_ENCRYPTION_IF_REQUIRED, "auto"},
+	{SMB_ENCRYPTION_DESIRED, "desired"},
+	{SMB_ENCRYPTION_REQUIRED, "required"},
+	{SMB_ENCRYPTION_REQUIRED, "mandatory"},
+	{SMB_ENCRYPTION_REQUIRED, "force"},
+	{SMB_ENCRYPTION_REQUIRED, "forced"},
+	{SMB_ENCRYPTION_REQUIRED, "enforced"},
+	{-1, NULL}
+};
+
 static const struct enum_list enum_mdns_name_values[] = {
 	{MDNS_NAME_NETBIOS, "netbios"},
 	{MDNS_NAME_MDNS, "mdns"},
diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h
index b424b13cde4..2fb1fd7189e 100644
--- a/libcli/smb/smb_constants.h
+++ b/libcli/smb/smb_constants.h
@@ -106,6 +106,15 @@ enum smb_signing_setting {
 	SMB_SIGNING_REQUIRED = 3,
 };
 
+/* This MUST align with 'enum smb_signing_setting' */
+enum smb_encryption_setting {
+	SMB_ENCRYPTION_DEFAULT = SMB_SIGNING_DEFAULT,
+	SMB_ENCRYPTION_OFF = SMB_SIGNING_OFF,
+	SMB_ENCRYPTION_IF_REQUIRED = SMB_SIGNING_IF_REQUIRED,
+	SMB_ENCRYPTION_DESIRED = SMB_SIGNING_DESIRED,
+	SMB_ENCRYPTION_REQUIRED = SMB_SIGNING_REQUIRED,
+};
+
 /* types of buffers in core SMB protocol */
 #define SMB_DATA_BLOCK 0x1
 #define SMB_ASCII4     0x4
-- 
2.29.2


From e2e0decfb117a8d6bb1428509f770315849e972b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 26 May 2020 09:34:54 +0200
Subject: [PATCH 006/104] s3:smbd: Use 'enum smb_encryption_setting' values

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/param/loadparm.c      | 2 +-
 source3/smbd/service.c        | 8 ++++----
 source3/smbd/smb2_negprot.c   | 2 +-
 source3/smbd/smb2_sesssetup.c | 4 ++--
 source3/smbd/smb2_tcon.c      | 4 ++--
 source3/smbd/trans2.c         | 3 ++-
 6 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index c0070b716a5..4ad541301b3 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -241,7 +241,7 @@ static const struct loadparm_service _sDefault =
 	.aio_write_size = 1,
 	.map_readonly = MAP_READONLY_NO,
 	.directory_name_cache_size = 100,
-	.server_smb_encrypt = SMB_SIGNING_DEFAULT,
+	.server_smb_encrypt = SMB_ENCRYPTION_DEFAULT,
 	.kernel_share_modes = true,
 	.durable_handles = true,
 	.check_parent_directory_delete_on_close = false,
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index a263c33b7e2..43803e721c2 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -568,16 +568,16 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn,
 	conn->short_case_preserve = lp_short_preserve_case(snum);
 
 	conn->encrypt_level = lp_server_smb_encrypt(snum);
-	if (conn->encrypt_level > SMB_SIGNING_OFF) {
-		if (lp_server_smb_encrypt(-1) == SMB_SIGNING_OFF) {
-			if (conn->encrypt_level == SMB_SIGNING_REQUIRED) {
+	if (conn->encrypt_level > SMB_ENCRYPTION_OFF) {
+		if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_OFF) {
+			if (conn->encrypt_level == SMB_ENCRYPTION_REQUIRED) {
 				DBG_ERR("Service [%s] requires encryption, but "
 					"it is disabled globally!\n",
 					lp_const_servicename(snum));
 				status = NT_STATUS_ACCESS_DENIED;
 				goto err_root_exit;
 			}
-			conn->encrypt_level = SMB_SIGNING_OFF;
+			conn->encrypt_level = SMB_ENCRYPTION_OFF;
 		}
 	}
 
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 674942b71de..99303f1b07b 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -335,7 +335,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
 	}
 
 	if ((protocol >= PROTOCOL_SMB2_24) &&
-	    (lp_server_smb_encrypt(-1) != SMB_SIGNING_OFF) &&
+	    (lp_server_smb_encrypt(-1) != SMB_ENCRYPTION_OFF) &&
 	    (in_capabilities & SMB2_CAP_ENCRYPTION)) {
 		capabilities |= SMB2_CAP_ENCRYPTION;
 	}
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 8957411e167..907dd92321e 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -292,12 +292,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 		x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED;
 	}
 
-	if ((lp_server_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) &&
+	if ((lp_server_smb_encrypt(-1) >= SMB_ENCRYPTION_DESIRED) &&
 	    (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) {
 		x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED;
 	}
 
-	if (lp_server_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) {
+	if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_REQUIRED) {
 		x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED |
 			SMBXSRV_ENCRYPTION_DESIRED;
 	}
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 0dd3c653b4b..d7e0cf90f47 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -302,13 +302,13 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 		TALLOC_FREE(proxy);
 	}
 
-	if ((lp_server_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) &&
+	if ((lp_server_smb_encrypt(snum) >= SMB_ENCRYPTION_DESIRED) &&
 	    (conn->smb2.server.cipher != 0))
 	{
 		encryption_desired = true;
 	}
 
-	if (lp_server_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) {
+	if (lp_server_smb_encrypt(snum) == SMB_ENCRYPTION_REQUIRED) {
 		encryption_desired = true;
 		encryption_required = true;
 	}
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index b745e0906b1..2f2fdcb7260 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4484,7 +4484,8 @@ static void call_trans2setfsinfo(connection_struct *conn,
 					return;
 				}
 
-				if (lp_server_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) {
+				if (lp_server_smb_encrypt(SNUM(conn)) ==
+				    SMB_ENCRYPTION_OFF) {
 					reply_nterror(
 						req,
 						NT_STATUS_NOT_SUPPORTED);
-- 
2.29.2


From a461b9e0348f2f082cc59b601271ca5b3283df09 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 9 Apr 2020 10:38:41 +0200
Subject: [PATCH 007/104] docs-xml: Add 'client smb encrypt'

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 .../smbdotconf/security/clientsmbencrypt.xml  | 126 ++++++++++++++++++
 lib/param/loadparm.c                          |   4 +
 source3/param/loadparm.c                      |   2 +
 3 files changed, 132 insertions(+)
 create mode 100644 docs-xml/smbdotconf/security/clientsmbencrypt.xml

diff --git a/docs-xml/smbdotconf/security/clientsmbencrypt.xml b/docs-xml/smbdotconf/security/clientsmbencrypt.xml
new file mode 100644
index 00000000000..05df152e734
--- /dev/null
+++ b/docs-xml/smbdotconf/security/clientsmbencrypt.xml
@@ -0,0 +1,126 @@
+<samba:parameter name="client smb encrypt"
+		 context="G"
+		 type="enum"
+		 enumlist="enum_smb_encryption_vals"
+		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+	<para>
+	This parameter controls whether a client should try or is required
+	to use SMB encryption. It has different effects depending on whether
+	the connection uses SMB1 or SMB3:
+	</para>
+
+	<itemizedlist>
+	<listitem>
+		<para>
+		If the connection uses SMB1, then this option controls the use
+		of a Samba-specific extension to the SMB protocol introduced in
+		Samba 3.2 that makes use of the Unix extensions.
+		</para>
+	</listitem>
+
+	<listitem>
+		<para>
+		If the connection uses SMB2 or newer, then this option controls
+		the use of the SMB-level encryption that is supported in SMB
+		version 3.0 and above and available in Windows 8 and newer.
+		</para>
+	</listitem>
+	</itemizedlist>
+
+	<para>
+		This parameter can be set globally. Possible values are
+
+		<emphasis>off</emphasis>,
+		<emphasis>if_required</emphasis>,
+		<emphasis>desired</emphasis>,
+		and
+		<emphasis>required</emphasis>.
+		A special value is <emphasis>default</emphasis> which is
+		the implicit default setting of <emphasis>if_required</emphasis>.
+	</para>
+
+	<variablelist>
+		<varlistentry>
+		<term><emphasis>Effects for SMB1</emphasis></term>
+		<listitem>
+		<para>
+		The Samba-specific encryption of SMB1 connections is an
+		extension to the SMB protocol negotiated as part of the UNIX
+		extensions.  SMB encryption uses the GSSAPI (SSPI on Windows)
+		ability to encrypt and sign every request/response in a SMB
+		protocol stream. When enabled it provides a secure method of
+		SMB/CIFS communication, similar to an ssh protected session, but
+		using SMB/CIFS authentication to negotiate encryption and
+		signing keys. Currently this is only supported smbclient of by
+		Samba 3.2 and newer. Windows does not support this feature.
+		</para>
+
+		<para>
+		When set to default, SMB encryption is probed, but not
+		enforced.  When set to required, SMB encryption is required and
+		if set to disabled, SMB encryption can not be negotiated.
+		</para>
+		</listitem>
+		</varlistentry>
+
+		<varlistentry>
+		<term><emphasis>Effects for SMB3 and newer</emphasis></term>
+		<listitem>
+		<para>
+		Native SMB transport encryption is available in SMB version 3.0
+		or newer. It is only used by Samba if
+		<emphasis>client max protocol</emphasis> is set to
+		<emphasis>SMB3</emphasis> or newer.
+		</para>
+
+		<para>
+		These features can be controlled with settings of
+		<emphasis>client smb encrypt</emphasis> as follows:
+		</para>
+
+		<itemizedlist>
+			<listitem>
+			<para>
+			Leaving it as default, explicitly setting
+			<emphasis>default</emphasis>, or setting it to
+			<emphasis>if_required</emphasis> globally will enable
+			negotiation of encryption but will not turn on
+			data encryption globally.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>desired</emphasis> globally
+			will enable negotiation and will turn on data encryption
+			on sessions and share connections for those servers
+			that support it.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>required</emphasis> globally
+			will enable negotiation and turn on data encryption
+			on sessions and share connections. Clients that do
+			not support encryption will be denied access to the
+			server.
+			</para>
+			</listitem>
+
+			<listitem>
+			<para>
+			Setting it to <emphasis>off</emphasis> globally will
+			completely disable the encryption feature for all
+			connections.
+			</para>
+			</listitem>
+		</itemizedlist>
+		</listitem>
+		</varlistentry>
+	</variablelist>
+</description>
+
+<value type="default">default</value>
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 006caabc092..67f5709b213 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -3079,6 +3079,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lpcfg_do_global_parameter(
 		lp_ctx, "ldap max search request size", "256000");
 
+	lpcfg_do_global_parameter(lp_ctx,
+				  "client smb encrypt",
+				  "default");
+
 	for (i = 0; parm_table[i].label; i++) {
 		if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
 			lp_ctx->flags[i] |= FLAG_DEFAULT;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 4ad541301b3..6418a42b6eb 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -960,6 +960,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 	Globals.ldap_max_authenticated_request_size = 16777216;
 	Globals.ldap_max_search_request_size = 256000;
 
+	Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT;
+
 	/* Now put back the settings that were set with lp_set_cmdline() */
 	apply_lp_set_cmdline();
 }
-- 
2.29.2


From d55143fc3090b43390fdf14ff45d9c2971fc43d2 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 22 Jul 2020 17:48:25 +0200
Subject: [PATCH 008/104] lib:param: Add lpcfg_parse_enum_vals()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 lib/param/loadparm.c | 30 ++++++++++++++++++++++++++++++
 lib/param/loadparm.h |  2 ++
 2 files changed, 32 insertions(+)

diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 67f5709b213..b1410791c60 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -3675,3 +3675,33 @@ char *lpcfg_substituted_string(TALLOC_CTX *mem_ctx,
 					     raw_value,
 					     lp_sub->private_data);
 }
+
+/**
+ * @brief Parse a string value of a given parameter to its integer enum value.
+ *
+ * @param[in]  param_name    The parameter name (e.g. 'client smb encrypt')
+ *
+ * @param[in]  param_value   The parameter value (e.g. 'required').
+ *
+ * @return The integer value of the enum the param_value matches or INT32_MIN
+ * on error.
+ */
+int32_t lpcfg_parse_enum_vals(const char *param_name,
+			      const char *param_value)
+{
+	struct parm_struct *parm = NULL;
+	int32_t ret = INT32_MIN;
+	bool ok;
+
+	parm = lpcfg_parm_struct(NULL, param_name);
+	if (parm == NULL) {
+		return INT32_MIN;
+	}
+
+	ok = lp_set_enum_parm(parm, param_value, &ret);
+	if (!ok) {
+		return INT32_MIN;
+	}
+
+	return ret;
+}
diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h
index 323fcf84523..e66ce2324b4 100644
--- a/lib/param/loadparm.h
+++ b/lib/param/loadparm.h
@@ -316,6 +316,8 @@ bool lp_do_section(const char *pszSectionName, void *userdata);
 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue);
 
 int num_parameters(void);
+int32_t lpcfg_parse_enum_vals(const char *param_name,
+			      const char *param_value);
 
 struct loadparm_substitution;
 #ifdef LOADPARM_SUBSTITUTION_INTERNALS
-- 
2.29.2


From d01ae8111553a71b80988eeb737e8b80bc765b20 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 9 Oct 2019 09:38:08 +0200
Subject: [PATCH 009/104] libcli:smb: Add smb_signing_setting_translate()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 libcli/smb/smb_util.h            |  7 ++++
 libcli/smb/test_util_translate.c | 64 ++++++++++++++++++++++++++++++++
 libcli/smb/util.c                | 20 ++++++++++
 libcli/smb/wscript               |  5 +++
 selftest/tests.py                |  2 +
 5 files changed, 98 insertions(+)
 create mode 100644 libcli/smb/test_util_translate.c

diff --git a/libcli/smb/smb_util.h b/libcli/smb/smb_util.h
index 8861741c92f..15bdbe856d1 100644
--- a/libcli/smb/smb_util.h
+++ b/libcli/smb/smb_util.h
@@ -24,6 +24,9 @@
 #include "smb_constants.h"
 #include <talloc.h>
 
+#ifndef _SMB_UTIL_H
+#define _SMB_UTIL_H
+
 const char *smb_protocol_types_string(enum protocol_types protocol);
 char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib);
 uint32_t unix_perms_to_wire(mode_t perms);
@@ -46,3 +49,7 @@ NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2,
 			    const uint8_t *buf, size_t buf_len,
 			    const uint8_t *position,
 			    size_t *_consumed);
+
+enum smb_signing_setting smb_signing_setting_translate(const char *str);
+
+#endif /* _SMB_UTIL_H */
diff --git a/libcli/smb/test_util_translate.c b/libcli/smb/test_util_translate.c
new file mode 100644
index 00000000000..4b81984affa
--- /dev/null
+++ b/libcli/smb/test_util_translate.c
@@ -0,0 +1,64 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2020      Andreas Schneider <asn@samba.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include <talloc.h>
+
+#include "libcli/smb/util.c"
+
+static void test_smb_signing_setting_translate(void **state)
+{
+	enum smb_signing_setting signing_state;
+
+	signing_state = smb_signing_setting_translate("wurst");
+	assert_int_equal(signing_state, SMB_SIGNING_REQUIRED);
+
+	signing_state = smb_signing_setting_translate("off");
+	assert_int_equal(signing_state, SMB_SIGNING_OFF);
+
+	signing_state = smb_signing_setting_translate("if_required");
+	assert_int_equal(signing_state, SMB_SIGNING_IF_REQUIRED);
+
+	signing_state = smb_signing_setting_translate("mandatory");
+	assert_int_equal(signing_state, SMB_SIGNING_REQUIRED);
+
+}
+
+int main(int argc, char *argv[])
+{
+	int rc;
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(test_smb_signing_setting_translate),
+	};
+
+	if (argc == 2) {
+		cmocka_set_test_filter(argv[1]);
+	}
+	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+	rc = cmocka_run_group_tests(tests, NULL, NULL);
+
+	return rc;
+}
diff --git a/libcli/smb/util.c b/libcli/smb/util.c
index 6fdf35fbbf3..da0e4db2bf3 100644
--- a/libcli/smb/util.c
+++ b/libcli/smb/util.c
@@ -22,6 +22,7 @@
 #include "includes.h"
 #include "libcli/smb/smb_common.h"
 #include "system/filesys.h"
+#include "lib/param/loadparm.h"
 
 const char *smb_protocol_types_string(enum protocol_types protocol)
 {
@@ -428,3 +429,22 @@ NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2,
 	return internal_bytes_pull_str(mem_ctx, _str, ucs2, true,
 				       buf, buf_len, position, _consumed);
 }
+
+/**
+ * @brief Translate SMB signing settings as string to an enum.
+ *
+ * @param[in]  str  The string to translate.
+ *
+ * @return A corresponding enum @smb_signing_setting tranlated from the string.
+ */
+enum smb_signing_setting smb_signing_setting_translate(const char *str)
+{
+	enum smb_signing_setting signing_state = SMB_SIGNING_REQUIRED;
+	int32_t val = lpcfg_parse_enum_vals("client signing", str);
+
+	if (val != INT32_MIN) {
+		signing_state = val;
+	}
+
+	return signing_state;
+}
diff --git a/libcli/smb/wscript b/libcli/smb/wscript
index 86e377f570b..c047fd33278 100644
--- a/libcli/smb/wscript
+++ b/libcli/smb/wscript
@@ -72,3 +72,8 @@ def build(bld):
                      source='test_smb1cli_session.c',
                      deps='cmocka cli_smb_common',
                      for_selftest=True)
+
+    bld.SAMBA_BINARY('test_util_translate',
+                     source='test_util_translate.c',
+                     deps='cmocka cli_smb_common',
+                     for_selftest=True)
diff --git a/selftest/tests.py b/selftest/tests.py
index 6918e1306c3..20981754db4 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -376,6 +376,8 @@ plantestsuite("samba.unittests.lib_util_modules", "none",
 
 plantestsuite("samba.unittests.smb1cli_session", "none",
               [os.path.join(bindir(), "default/libcli/smb/test_smb1cli_session")])
+plantestsuite("samba.unittests.smb_util_translate", "none",
+              [os.path.join(bindir(), "default/libcli/smb/test_util_translate")])
 
 plantestsuite("samba.unittests.talloc_keep_secret", "none",
               [os.path.join(bindir(), "default/lib/util/test_talloc_keep_secret")])
-- 
2.29.2


From 4cef2825a3363a38fbfbff5f172053145f62f100 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 26 May 2020 08:39:34 +0200
Subject: [PATCH 010/104] libcli:smb: Add smb_encryption_setting_translate()

Add encryption enum and function to avoid confusion when reading the
code.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 libcli/smb/smb_util.h            |  1 +
 libcli/smb/test_util_translate.c | 19 +++++++++++++++++++
 libcli/smb/util.c                | 20 ++++++++++++++++++++
 3 files changed, 40 insertions(+)

diff --git a/libcli/smb/smb_util.h b/libcli/smb/smb_util.h
index 15bdbe856d1..2a727db8b6f 100644
--- a/libcli/smb/smb_util.h
+++ b/libcli/smb/smb_util.h
@@ -51,5 +51,6 @@ NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2,
 			    size_t *_consumed);
 
 enum smb_signing_setting smb_signing_setting_translate(const char *str);
+enum smb_encryption_setting smb_encryption_setting_translate(const char *str);
 
 #endif /* _SMB_UTIL_H */
diff --git a/libcli/smb/test_util_translate.c b/libcli/smb/test_util_translate.c
index 4b81984affa..b300af52c09 100644
--- a/libcli/smb/test_util_translate.c
+++ b/libcli/smb/test_util_translate.c
@@ -46,11 +46,30 @@ static void test_smb_signing_setting_translate(void **state)
 
 }
 
+static void test_smb_encryption_setting_translate(void **state)
+{
+	enum smb_encryption_setting encryption_state;
+
+	encryption_state = smb_encryption_setting_translate("wurst");
+	assert_int_equal(encryption_state, SMB_ENCRYPTION_REQUIRED);
+
+	encryption_state = smb_encryption_setting_translate("off");
+	assert_int_equal(encryption_state, SMB_ENCRYPTION_OFF);
+
+	encryption_state = smb_encryption_setting_translate("if_required");
+	assert_int_equal(encryption_state, SMB_ENCRYPTION_IF_REQUIRED);
+
+	encryption_state = smb_encryption_setting_translate("mandatory");
+	assert_int_equal(encryption_state, SMB_ENCRYPTION_REQUIRED);
+
+}
+
 int main(int argc, char *argv[])
 {
 	int rc;
 	const struct CMUnitTest tests[] = {
 		cmocka_unit_test(test_smb_signing_setting_translate),
+		cmocka_unit_test(test_smb_encryption_setting_translate),
 	};
 
 	if (argc == 2) {
diff --git a/libcli/smb/util.c b/libcli/smb/util.c
index da0e4db2bf3..ac2887ee5c4 100644
--- a/libcli/smb/util.c
+++ b/libcli/smb/util.c
@@ -448,3 +448,23 @@ enum smb_signing_setting smb_signing_setting_translate(const char *str)
 
 	return signing_state;
 }
+
+/**
+ * @brief Translate SMB encryption settings as string to an enum.
+ *
+ * @param[in]  str  The string to translate.
+ *
+ * @return A corresponding enum @smb_encryption_setting tranlated from the
+ *         string.
+ */
+enum smb_encryption_setting smb_encryption_setting_translate(const char *str)
+{
+	enum smb_encryption_setting encryption_state = SMB_ENCRYPTION_REQUIRED;
+	int32_t val = lpcfg_parse_enum_vals("client smb encrypt", str);
+
+	if (val != INT32_MIN) {
+		encryption_state = val;
+	}
+
+	return encryption_state;
+}
-- 
2.29.2


From a0cb6b810b655298ce5b87d8e36d1089460feca7 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 9 Oct 2019 09:47:59 +0200
Subject: [PATCH 011/104] s3:lib: Use smb_signing_setting_translate for cmdline
 parsing

The function will be removed soon.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/lib/util_cmdline.c | 17 +++--------------
 source3/wscript_build      |  2 +-
 2 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c
index 90ee67c4cb7..bc1f1c3ed25 100644
--- a/source3/lib/util_cmdline.c
+++ b/source3/lib/util_cmdline.c
@@ -28,6 +28,7 @@
 #include "librpc/gen_ndr/samr.h"
 #include "auth/credentials/credentials.h"
 #include "auth/gensec/gensec.h"
+#include "libcli/smb/smb_util.h"
 
 /**************************************************************************n
   Code to cope with username/password auth options from the commandline.
@@ -240,20 +241,8 @@ void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
 					 const char *arg)
 {
-	auth_info->signing_state = SMB_SIGNING_DEFAULT;
-	if (strequal(arg, "off") || strequal(arg, "no") ||
-			strequal(arg, "false")) {
-		auth_info->signing_state = SMB_SIGNING_OFF;
-	} else if (strequal(arg, "on") || strequal(arg, "yes") ||
-			strequal(arg, "if_required") ||
-			strequal(arg, "true") || strequal(arg, "auto")) {
-		auth_info->signing_state = SMB_SIGNING_IF_REQUIRED;
-	} else if (strequal(arg, "force") || strequal(arg, "required") ||
-			strequal(arg, "forced")) {
-		auth_info->signing_state = SMB_SIGNING_REQUIRED;
-	} else {
-		return false;
-	}
+	auth_info->signing_state = smb_signing_setting_translate(arg);
+
 	return true;
 }
 
diff --git a/source3/wscript_build b/source3/wscript_build
index 5a07eddac44..6a08afe4a25 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -279,7 +279,7 @@ bld.SAMBA3_LIBRARY('popt_samba3_cmdline',
 
 bld.SAMBA3_LIBRARY('util_cmdline',
                    source='lib/util_cmdline.c',
-                   deps='secrets3 samba-credentials',
+                   deps='secrets3 samba-credentials cli_smb_common',
                    private_library=True)
 
 bld.SAMBA3_LIBRARY('cmdline_contexts',
-- 
2.29.2


From ef521e6b44710fb3ed567d36fa56687b677fe58a Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 23 Jul 2020 07:47:18 +0200
Subject: [PATCH 012/104] auth:creds: Remove unused credentials autoproto
 header

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/credentials_krb5.c    | 1 -
 auth/credentials/credentials_secrets.c | 1 -
 auth/credentials/wscript_build         | 1 -
 source4/auth/kerberos/kerberos_util.c  | 1 -
 source4/auth/tests/kerberos.c          | 1 -
 5 files changed, 5 deletions(-)

diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index 20e677e521a..259b35b73b0 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -27,7 +27,6 @@
 #include "auth/kerberos/kerberos.h"
 #include "auth/credentials/credentials.h"
 #include "auth/credentials/credentials_internal.h"
-#include "auth/credentials/credentials_proto.h"
 #include "auth/credentials/credentials_krb5.h"
 #include "auth/kerberos/kerberos_credentials.h"
 #include "auth/kerberos/kerberos_srv_keytab.h"
diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c
index 54f3ce2d078..52a89d4d5b4 100644
--- a/auth/credentials/credentials_secrets.c
+++ b/auth/credentials/credentials_secrets.c
@@ -29,7 +29,6 @@
 #include "system/filesys.h"
 #include "auth/credentials/credentials.h"
 #include "auth/credentials/credentials_internal.h"
-#include "auth/credentials/credentials_proto.h"
 #include "auth/credentials/credentials_krb5.h"
 #include "auth/kerberos/kerberos_util.h"
 #include "param/param.h"
diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build
index f5aba1de248..564a04fe8dd 100644
--- a/auth/credentials/wscript_build
+++ b/auth/credentials/wscript_build
@@ -2,7 +2,6 @@
 
 bld.SAMBA_LIBRARY('samba-credentials',
 	source='credentials.c',
-	autoproto='credentials_proto.h',
 	public_headers='credentials.h',
 	pc_files='samba-credentials.pc',
 	deps='LIBCRYPTO samba-errors events LIBCLI_AUTH samba-security CREDENTIALS_SECRETS CREDENTIALS_KRB5',
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index ffef24f285c..544d9d853cc 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -24,7 +24,6 @@
 #include "system/kerberos.h"
 #include "auth/kerberos/kerberos.h"
 #include "auth/credentials/credentials.h"
-#include "auth/credentials/credentials_proto.h"
 #include "auth/credentials/credentials_krb5.h"
 #include "auth/kerberos/kerberos_credentials.h"
 #include "auth/kerberos/kerberos_util.h"
diff --git a/source4/auth/tests/kerberos.c b/source4/auth/tests/kerberos.c
index 7711eac2afa..d9be3562adb 100644
--- a/source4/auth/tests/kerberos.c
+++ b/source4/auth/tests/kerberos.c
@@ -10,7 +10,6 @@
 #include "system/kerberos.h"
 #include "auth/kerberos/kerberos.h"
 #include "auth/credentials/credentials.h"
-#include "auth/credentials/credentials_proto.h"
 #include "auth/credentials/credentials_krb5.h"
 #include "auth/kerberos/kerberos_credentials.h"
 #include "auth/kerberos/kerberos_util.h"
-- 
2.29.2


From 6fafcebb8bd6311a736d995af6641e68e43e03a1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 26 May 2020 09:32:44 +0200
Subject: [PATCH 013/104] auth:creds: Add
 cli_credentials_(get|set)_smb_signing()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/credentials.c          | 45 +++++++++++++++++++++++++
 auth/credentials/credentials.h          |  7 ++++
 auth/credentials/credentials_internal.h |  4 +++
 3 files changed, 56 insertions(+)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 80a31b248ae..365a6def7ea 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -44,6 +44,8 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 
 	cred->winbind_separator = '\\';
 
+	cred->signing_state = SMB_SIGNING_DEFAULT;
+
 	return cred;
 }
 
@@ -922,6 +924,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred,
 	if (sep != NULL && sep[0] != '\0') {
 		cred->winbind_separator = *lpcfg_winbind_separator(lp_ctx);
 	}
+
+	if (cred->signing_state_obtained <= CRED_SMB_CONF) {
+		/* Will be set to default for invalid smb.conf values */
+		cred->signing_state = lpcfg_client_signing(lp_ctx);
+		cred->signing_state_obtained = CRED_SMB_CONF;
+	}
 }
 
 /**
@@ -1304,6 +1312,43 @@ _PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credenti
 	return true;
 }
 
+/**
+ * @brief Set the SMB signing state to request for a SMB connection.
+ *
+ * @param[in]  creds          The credentials structure to update.
+ *
+ * @param[in]  signing_state  The signing state to set.
+ *
+ * @param obtained            This way the described signing state was specified.
+ *
+ * @return true if we could set the signing state, false otherwise.
+ */
+_PUBLIC_ bool cli_credentials_set_smb_signing(struct cli_credentials *creds,
+					      enum smb_signing_setting signing_state,
+					      enum credentials_obtained obtained)
+{
+	if (obtained >= creds->signing_state_obtained) {
+		creds->signing_state_obtained = obtained;
+		creds->signing_state = signing_state;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * @brief Obtain the SMB signing state from a credentials structure.
+ *
+ * @param[in]  creds  The credential structure to obtain the SMB signing state
+ *                    from.
+ *
+ * @return The SMB singing state.
+ */
+_PUBLIC_ enum smb_signing_setting
+cli_credentials_get_smb_signing(struct cli_credentials *creds)
+{
+	return creds->signing_state;
+}
 
 /**
  * Encrypt a data blob using the session key and the negotiated encryption
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 7154c2a008c..422391ad585 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -38,6 +38,7 @@ struct gssapi_creds_container;
 struct smb_krb5_context;
 struct keytab_container;
 struct db_context;
+enum smb_signing_setting;
 
 /* In order of priority */
 enum credentials_obtained { 
@@ -290,6 +291,12 @@ void *_cli_credentials_callback_data(struct cli_credentials *cred);
 #define cli_credentials_callback_data_void(_cred) \
 	_cli_credentials_callback_data(_cred)
 
+bool cli_credentials_set_smb_signing(struct cli_credentials *cred,
+				     enum smb_signing_setting signing_state,
+				     enum credentials_obtained obtained);
+enum smb_signing_setting
+cli_credentials_get_smb_signing(struct cli_credentials *cred);
+
 /**
  * Return attached NETLOGON credentials 
  */
diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h
index 68f1f25dce1..9cde0000b5f 100644
--- a/auth/credentials/credentials_internal.h
+++ b/auth/credentials/credentials_internal.h
@@ -24,6 +24,7 @@
 
 #include "../lib/util/data_blob.h"
 #include "librpc/gen_ndr/misc.h"
+#include "libcli/smb/smb_constants.h"
 
 struct cli_credentials {
 	enum credentials_obtained workstation_obtained;
@@ -36,6 +37,7 @@ struct cli_credentials {
 	enum credentials_obtained principal_obtained;
 	enum credentials_obtained keytab_obtained;
 	enum credentials_obtained server_gss_creds_obtained;
+	enum credentials_obtained signing_state_obtained;
 
 	/* Threshold values (essentially a MAX() over a number of the
 	 * above) for the ccache and GSS credentials, to ensure we
@@ -117,6 +119,8 @@ struct cli_credentials {
 	char winbind_separator;
 
 	bool password_will_be_nt_hash;
+
+	enum smb_signing_setting signing_state;
 };
 
 #endif /* __CREDENTIALS_INTERNAL_H__ */
-- 
2.29.2


From 64e2c99501677bfe52212c9ea99ec3512cf62f6e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 3 Jun 2020 11:56:01 +0200
Subject: [PATCH 014/104] auth:creds: Add python bindings for
 (get|set)_smb_signing

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/pycredentials.c  | 63 +++++++++++++++++++++++++++++++
 python/samba/tests/credentials.py |  6 +++
 2 files changed, 69 insertions(+)

diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index 68edc282741..846c418419f 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -34,6 +34,7 @@
 #include "auth/credentials/credentials_internal.h"
 #include "system/kerberos.h"
 #include "auth/kerberos/kerberos.h"
+#include "libcli/smb/smb_constants.h"
 
 void initcredentials(void);
 
@@ -929,6 +930,52 @@ static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self,
 	Py_RETURN_NONE;
 }
 
+static PyObject *py_creds_get_smb_signing(PyObject *self, PyObject *unused)
+{
+	enum smb_signing_setting signing_state;
+	struct cli_credentials *creds = NULL;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+
+	signing_state = cli_credentials_get_smb_signing(creds);
+	return PyLong_FromLong(signing_state);
+}
+
+static PyObject *py_creds_set_smb_signing(PyObject *self, PyObject *args)
+{
+	enum smb_signing_setting signing_state;
+	struct cli_credentials *creds = NULL;
+	enum credentials_obtained obt = CRED_SPECIFIED;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) {
+		return NULL;
+	}
+
+	switch (signing_state) {
+	case SMB_SIGNING_DEFAULT:
+	case SMB_SIGNING_OFF:
+	case SMB_SIGNING_IF_REQUIRED:
+	case SMB_SIGNING_DESIRED:
+	case SMB_SIGNING_REQUIRED:
+		break;
+	default:
+		PyErr_Format(PyExc_TypeError, "Invalid signing state value");
+		return NULL;
+	}
+
+	cli_credentials_set_smb_signing(creds, signing_state, obt);
+	Py_RETURN_NONE;
+}
+
 static PyMethodDef py_creds_methods[] = {
 	{
 		.ml_name  = "get_username",
@@ -1209,6 +1256,16 @@ static PyMethodDef py_creds_methods[] = {
 			    "Encrypt the supplied password using the session key and\n"
 			    "the negotiated encryption algorithm in place\n"
 			    "i.e. it overwrites the original data"},
+	{
+		.ml_name  = "get_smb_signing",
+		.ml_meth  = py_creds_get_smb_signing,
+		.ml_flags = METH_NOARGS,
+	},
+	{
+		.ml_name  = "set_smb_signing",
+		.ml_meth  = py_creds_set_smb_signing,
+		.ml_flags = METH_VARARGS,
+	},
 	{ .ml_name = NULL }
 };
 
@@ -1295,6 +1352,12 @@ MODULE_INIT_FUNC(credentials)
 	PyModule_AddObject(m, "CLI_CRED_NTLM_AUTH", PyLong_FromLong(CLI_CRED_NTLM_AUTH));
 	PyModule_AddObject(m, "CLI_CRED_CLEAR_AUTH", PyLong_FromLong(CLI_CRED_CLEAR_AUTH));
 
+	PyModule_AddObject(m, "SMB_SIGNING_DEFAULT", PyLong_FromLong(SMB_SIGNING_DEFAULT));
+	PyModule_AddObject(m, "SMB_SIGNING_OFF", PyLong_FromLong(SMB_SIGNING_OFF));
+	PyModule_AddObject(m, "SMB_SIGNING_IF_REQUIRED", PyLong_FromLong(SMB_SIGNING_IF_REQUIRED));
+	PyModule_AddObject(m, "SMB_SIGNING_DESIRED", PyLong_FromLong(SMB_SIGNING_DESIRED));
+	PyModule_AddObject(m, "SMB_SIGNING_REQUIRED", PyLong_FromLong(SMB_SIGNING_REQUIRED));
+
 	Py_INCREF(&PyCredentials);
 	PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
 	Py_INCREF(&PyCredentialCacheContainer);
diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py
index 6454ac9ff7c..e5f8122fa21 100644
--- a/python/samba/tests/credentials.py
+++ b/python/samba/tests/credentials.py
@@ -456,3 +456,9 @@ class CredentialsTests(samba.tests.TestCaseInTempDir):
         self.assertEqual(creds.get_principal(), "user@samba.org")
         self.assertEqual(creds.is_anonymous(), False)
         self.assertEqual(creds.authentication_requested(), True)
+
+    def test_smb_signing(self):
+        creds = credentials.Credentials()
+        self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_DEFAULT)
+        creds.set_smb_signing(credentials.SMB_SIGNING_REQUIRED)
+        self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_REQUIRED)
-- 
2.29.2


From 1280505f1396925851db5a29f2465d9c31d45f88 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 16:31:35 +0200
Subject: [PATCH 015/104] auth:creds: Add
 cli_credentials_(get|set)_smb_ipc_signing()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/credentials.c          | 51 +++++++++++++++++++++++++
 auth/credentials/credentials.h          |  6 +++
 auth/credentials/credentials_internal.h |  3 ++
 3 files changed, 60 insertions(+)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 365a6def7ea..dc5d51f1424 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -46,6 +46,12 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 
 	cred->signing_state = SMB_SIGNING_DEFAULT;
 
+	/*
+	 * The default value of lpcfg_client_ipc_signing() is REQUIRED, so use
+	 * the same value here.
+	 */
+	cred->ipc_signing_state = SMB_SIGNING_REQUIRED;
+
 	return cred;
 }
 
@@ -930,6 +936,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred,
 		cred->signing_state = lpcfg_client_signing(lp_ctx);
 		cred->signing_state_obtained = CRED_SMB_CONF;
 	}
+
+	if (cred->ipc_signing_state_obtained <= CRED_SMB_CONF) {
+		/* Will be set to required for invalid smb.conf values */
+		cred->ipc_signing_state = lpcfg_client_ipc_signing(lp_ctx);
+		cred->ipc_signing_state_obtained = CRED_SMB_CONF;
+	}
 }
 
 /**
@@ -1350,6 +1362,45 @@ cli_credentials_get_smb_signing(struct cli_credentials *creds)
 	return creds->signing_state;
 }
 
+/**
+ * @brief Set the SMB IPC signing state to request for a SMB connection.
+ *
+ * @param[in]  creds          The credentials structure to update.
+ *
+ * @param[in]  signing_state  The signing state to set.
+ *
+ * @param obtained            This way the described signing state was specified.
+ *
+ * @return true if we could set the signing state, false otherwise.
+ */
+_PUBLIC_ bool
+cli_credentials_set_smb_ipc_signing(struct cli_credentials *creds,
+				    enum smb_signing_setting ipc_signing_state,
+				    enum credentials_obtained obtained)
+{
+	if (obtained >= creds->ipc_signing_state_obtained) {
+		creds->ipc_signing_state_obtained = obtained;
+		creds->ipc_signing_state = ipc_signing_state;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * @brief Obtain the SMB IPC signing state from a credentials structure.
+ *
+ * @param[in]  creds  The credential structure to obtain the SMB IPC signing
+ *                    state from.
+ *
+ * @return The SMB singing state.
+ */
+_PUBLIC_ enum smb_signing_setting
+cli_credentials_get_smb_ipc_signing(struct cli_credentials *creds)
+{
+	return creds->ipc_signing_state;
+}
+
 /**
  * Encrypt a data blob using the session key and the negotiated encryption
  * algorithm
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 422391ad585..25bec916278 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -297,6 +297,12 @@ bool cli_credentials_set_smb_signing(struct cli_credentials *cred,
 enum smb_signing_setting
 cli_credentials_get_smb_signing(struct cli_credentials *cred);
 
+bool cli_credentials_set_smb_ipc_signing(struct cli_credentials *cred,
+					 enum smb_signing_setting ipc_signing_state,
+					 enum credentials_obtained obtained);
+enum smb_signing_setting
+cli_credentials_get_smb_ipc_signing(struct cli_credentials *cred);
+
 /**
  * Return attached NETLOGON credentials 
  */
diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h
index 9cde0000b5f..54e8271471f 100644
--- a/auth/credentials/credentials_internal.h
+++ b/auth/credentials/credentials_internal.h
@@ -38,6 +38,7 @@ struct cli_credentials {
 	enum credentials_obtained keytab_obtained;
 	enum credentials_obtained server_gss_creds_obtained;
 	enum credentials_obtained signing_state_obtained;
+	enum credentials_obtained ipc_signing_state_obtained;
 
 	/* Threshold values (essentially a MAX() over a number of the
 	 * above) for the ccache and GSS credentials, to ensure we
@@ -121,6 +122,8 @@ struct cli_credentials {
 	bool password_will_be_nt_hash;
 
 	enum smb_signing_setting signing_state;
+
+	enum smb_signing_setting ipc_signing_state;
 };
 
 #endif /* __CREDENTIALS_INTERNAL_H__ */
-- 
2.29.2


From 32209d254bb7bd3bd6ad3af14f219cee306a19a3 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 3 Jun 2020 12:32:46 +0200
Subject: [PATCH 016/104] auth:creds: Add python bindings for
 (get|set)_smb_ipc_signing

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/pycredentials.c  | 56 +++++++++++++++++++++++++++++++
 python/samba/tests/credentials.py |  6 ++++
 2 files changed, 62 insertions(+)

diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index 846c418419f..1a83c506088 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -976,6 +976,52 @@ static PyObject *py_creds_set_smb_signing(PyObject *self, PyObject *args)
 	Py_RETURN_NONE;
 }
 
+static PyObject *py_creds_get_smb_ipc_signing(PyObject *self, PyObject *unused)
+{
+	enum smb_signing_setting signing_state;
+	struct cli_credentials *creds = NULL;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+
+	signing_state = cli_credentials_get_smb_ipc_signing(creds);
+	return PyLong_FromLong(signing_state);
+}
+
+static PyObject *py_creds_set_smb_ipc_signing(PyObject *self, PyObject *args)
+{
+	enum smb_signing_setting signing_state;
+	struct cli_credentials *creds = NULL;
+	enum credentials_obtained obt = CRED_SPECIFIED;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) {
+		return NULL;
+	}
+
+	switch (signing_state) {
+	case SMB_SIGNING_DEFAULT:
+	case SMB_SIGNING_OFF:
+	case SMB_SIGNING_IF_REQUIRED:
+	case SMB_SIGNING_DESIRED:
+	case SMB_SIGNING_REQUIRED:
+		break;
+	default:
+		PyErr_Format(PyExc_TypeError, "Invalid signing state value");
+		return NULL;
+	}
+
+	cli_credentials_set_smb_ipc_signing(creds, signing_state, obt);
+	Py_RETURN_NONE;
+}
+
 static PyMethodDef py_creds_methods[] = {
 	{
 		.ml_name  = "get_username",
@@ -1266,6 +1312,16 @@ static PyMethodDef py_creds_methods[] = {
 		.ml_meth  = py_creds_set_smb_signing,
 		.ml_flags = METH_VARARGS,
 	},
+	{
+		.ml_name  = "get_smb_ipc_signing",
+		.ml_meth  = py_creds_get_smb_ipc_signing,
+		.ml_flags = METH_NOARGS,
+	},
+	{
+		.ml_name  = "set_smb_ipc_signing",
+		.ml_meth  = py_creds_set_smb_ipc_signing,
+		.ml_flags = METH_VARARGS,
+	},
 	{ .ml_name = NULL }
 };
 
diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py
index e5f8122fa21..8edf13ce6ff 100644
--- a/python/samba/tests/credentials.py
+++ b/python/samba/tests/credentials.py
@@ -462,3 +462,9 @@ class CredentialsTests(samba.tests.TestCaseInTempDir):
         self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_DEFAULT)
         creds.set_smb_signing(credentials.SMB_SIGNING_REQUIRED)
         self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_REQUIRED)
+
+    def test_smb_ipc_signing(self):
+        creds = credentials.Credentials()
+        self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED)
+        creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF)
+        self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF)
-- 
2.29.2


From d0a1bf1a75426c1d334349a6a4f8e44c80c1915b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 16:10:52 +0200
Subject: [PATCH 017/104] auth:creds: Add
 cli_credentials_(get|set)_smb_encryption()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/credentials.c          | 45 +++++++++++++++++++++++++
 auth/credentials/credentials.h          |  7 ++++
 auth/credentials/credentials_internal.h |  3 ++
 3 files changed, 55 insertions(+)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index dc5d51f1424..9168b92d3ec 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -51,6 +51,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 	 * the same value here.
 	 */
 	cred->ipc_signing_state = SMB_SIGNING_REQUIRED;
+	cred->encryption_state = SMB_ENCRYPTION_DEFAULT;
 
 	return cred;
 }
@@ -942,6 +943,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred,
 		cred->ipc_signing_state = lpcfg_client_ipc_signing(lp_ctx);
 		cred->ipc_signing_state_obtained = CRED_SMB_CONF;
 	}
+
+	if (cred->encryption_state_obtained <= CRED_SMB_CONF) {
+		/* Will be set to default for invalid smb.conf values */
+		cred->encryption_state = lpcfg_client_smb_encrypt(lp_ctx);
+		cred->encryption_state_obtained = CRED_SMB_CONF;
+	}
 }
 
 /**
@@ -1401,6 +1408,44 @@ cli_credentials_get_smb_ipc_signing(struct cli_credentials *creds)
 	return creds->ipc_signing_state;
 }
 
+/**
+ * @brief Set the SMB encryption state to request for a SMB connection.
+ *
+ * @param[in]  creds  The credentials structure to update.
+ *
+ * @param[in]  encryption_state  The encryption state to set.
+ *
+ * @param obtained  This way the described encryption state was specified.
+ *
+ * @return true if we could set the encryption state, false otherwise.
+ */
+_PUBLIC_ bool cli_credentials_set_smb_encryption(struct cli_credentials *creds,
+						 enum smb_encryption_setting encryption_state,
+						 enum credentials_obtained obtained)
+{
+	if (obtained >= creds->encryption_state_obtained) {
+		creds->encryption_state_obtained = obtained;
+		creds->encryption_state = encryption_state;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * @brief Obtain the SMB encryption state from a credentials structure.
+ *
+ * @param[in]  creds  The credential structure to obtain the SMB encryption state
+ *                    from.
+ *
+ * @return The SMB singing state.
+ */
+_PUBLIC_ enum smb_encryption_setting
+cli_credentials_get_smb_encryption(struct cli_credentials *creds)
+{
+	return creds->encryption_state;
+}
+
 /**
  * Encrypt a data blob using the session key and the negotiated encryption
  * algorithm
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 25bec916278..7d0cf53194b 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -39,6 +39,7 @@ struct smb_krb5_context;
 struct keytab_container;
 struct db_context;
 enum smb_signing_setting;
+enum smb_encryption_setting;
 
 /* In order of priority */
 enum credentials_obtained { 
@@ -303,6 +304,12 @@ bool cli_credentials_set_smb_ipc_signing(struct cli_credentials *cred,
 enum smb_signing_setting
 cli_credentials_get_smb_ipc_signing(struct cli_credentials *cred);
 
+bool cli_credentials_set_smb_encryption(struct cli_credentials *cred,
+					enum smb_encryption_setting encryption_state,
+					enum credentials_obtained obtained);
+enum smb_encryption_setting
+cli_credentials_get_smb_encryption(struct cli_credentials *cred);
+
 /**
  * Return attached NETLOGON credentials 
  */
diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h
index 54e8271471f..3b86b742448 100644
--- a/auth/credentials/credentials_internal.h
+++ b/auth/credentials/credentials_internal.h
@@ -39,6 +39,7 @@ struct cli_credentials {
 	enum credentials_obtained server_gss_creds_obtained;
 	enum credentials_obtained signing_state_obtained;
 	enum credentials_obtained ipc_signing_state_obtained;
+	enum credentials_obtained encryption_state_obtained;
 
 	/* Threshold values (essentially a MAX() over a number of the
 	 * above) for the ccache and GSS credentials, to ensure we
@@ -124,6 +125,8 @@ struct cli_credentials {
 	enum smb_signing_setting signing_state;
 
 	enum smb_signing_setting ipc_signing_state;
+
+	enum smb_encryption_setting encryption_state;
 };
 
 #endif /* __CREDENTIALS_INTERNAL_H__ */
-- 
2.29.2


From 36ab2aa54102aa9cce92ac8ebf250db4d460324e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 3 Jun 2020 12:38:30 +0200
Subject: [PATCH 018/104] auth:creds: Add python bindings for
 (get|set)_smb_encryption

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/pycredentials.c  | 62 +++++++++++++++++++++++++++++++
 python/samba/tests/credentials.py |  6 +++
 2 files changed, 68 insertions(+)

diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index 1a83c506088..628aae6500b 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -1022,6 +1022,52 @@ static PyObject *py_creds_set_smb_ipc_signing(PyObject *self, PyObject *args)
 	Py_RETURN_NONE;
 }
 
+static PyObject *py_creds_get_smb_encryption(PyObject *self, PyObject *unused)
+{
+	enum smb_encryption_setting encryption_state;
+	struct cli_credentials *creds = NULL;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+
+	encryption_state = cli_credentials_get_smb_encryption(creds);
+	return PyLong_FromLong(encryption_state);
+}
+
+static PyObject *py_creds_set_smb_encryption(PyObject *self, PyObject *args)
+{
+	enum smb_encryption_setting encryption_state;
+	struct cli_credentials *creds = NULL;
+	enum credentials_obtained obt = CRED_SPECIFIED;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+	if (!PyArg_ParseTuple(args, "i|i", &encryption_state, &obt)) {
+		return NULL;
+	}
+
+	switch (encryption_state) {
+	case SMB_ENCRYPTION_DEFAULT:
+	case SMB_ENCRYPTION_OFF:
+	case SMB_ENCRYPTION_IF_REQUIRED:
+	case SMB_ENCRYPTION_DESIRED:
+	case SMB_ENCRYPTION_REQUIRED:
+		break;
+	default:
+		PyErr_Format(PyExc_TypeError, "Invalid encryption state value");
+		return NULL;
+	}
+
+	cli_credentials_set_smb_encryption(creds, encryption_state, obt);
+	Py_RETURN_NONE;
+}
+
 static PyMethodDef py_creds_methods[] = {
 	{
 		.ml_name  = "get_username",
@@ -1322,6 +1368,16 @@ static PyMethodDef py_creds_methods[] = {
 		.ml_meth  = py_creds_set_smb_ipc_signing,
 		.ml_flags = METH_VARARGS,
 	},
+	{
+		.ml_name  = "get_smb_encryption",
+		.ml_meth  = py_creds_get_smb_encryption,
+		.ml_flags = METH_NOARGS,
+	},
+	{
+		.ml_name  = "set_smb_encryption",
+		.ml_meth  = py_creds_set_smb_encryption,
+		.ml_flags = METH_VARARGS,
+	},
 	{ .ml_name = NULL }
 };
 
@@ -1414,6 +1470,12 @@ MODULE_INIT_FUNC(credentials)
 	PyModule_AddObject(m, "SMB_SIGNING_DESIRED", PyLong_FromLong(SMB_SIGNING_DESIRED));
 	PyModule_AddObject(m, "SMB_SIGNING_REQUIRED", PyLong_FromLong(SMB_SIGNING_REQUIRED));
 
+	PyModule_AddObject(m, "SMB_ENCRYPTION_DEFAULT", PyLong_FromLong(SMB_ENCRYPTION_DEFAULT));
+	PyModule_AddObject(m, "SMB_ENCRYPTION_OFF", PyLong_FromLong(SMB_ENCRYPTION_OFF));
+	PyModule_AddObject(m, "SMB_ENCRYPTION_IF_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_IF_REQUIRED));
+	PyModule_AddObject(m, "SMB_ENCRYPTION_DESIRED", PyLong_FromLong(SMB_ENCRYPTION_DESIRED));
+	PyModule_AddObject(m, "SMB_ENCRYPTION_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_REQUIRED));
+
 	Py_INCREF(&PyCredentials);
 	PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials);
 	Py_INCREF(&PyCredentialCacheContainer);
diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py
index 8edf13ce6ff..e0a6248d37a 100644
--- a/python/samba/tests/credentials.py
+++ b/python/samba/tests/credentials.py
@@ -468,3 +468,9 @@ class CredentialsTests(samba.tests.TestCaseInTempDir):
         self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED)
         creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF)
         self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF)
+
+    def test_smb_encryption(self):
+        creds = credentials.Credentials()
+        self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_DEFAULT)
+        creds.set_smb_encryption(credentials.SMB_ENCRYPTION_REQUIRED)
+        self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_REQUIRED)
-- 
2.29.2


From f866d9e80964e16307a8376ed448d0ca3a987538 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 4 Jun 2020 11:19:53 +0200
Subject: [PATCH 019/104] auth:creds: Add python bindings for
 cli_credentials_set_conf()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/pycredentials.c  | 41 +++++++++++++++++++++++++++++++
 python/samba/tests/credentials.py | 33 +++++++++++++++++++++++++
 2 files changed, 74 insertions(+)

diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index 628aae6500b..17c90573f09 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -621,6 +621,42 @@ static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args)
 	Py_RETURN_NONE;
 }
 
+static PyObject *py_creds_set_conf(PyObject *self, PyObject *args)
+{
+	PyObject *py_lp_ctx = Py_None;
+	struct loadparm_context *lp_ctx;
+	TALLOC_CTX *mem_ctx;
+	struct cli_credentials *creds;
+
+	creds = PyCredentials_AsCliCredentials(self);
+	if (creds == NULL) {
+		PyErr_Format(PyExc_TypeError, "Credentials expected");
+		return NULL;
+	}
+
+	if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx)) {
+		return NULL;
+	}
+
+	mem_ctx = talloc_new(NULL);
+	if (mem_ctx == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
+
+	lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
+	if (lp_ctx == NULL) {
+		talloc_free(mem_ctx);
+		return NULL;
+	}
+
+	cli_credentials_set_conf(creds, lp_ctx);
+
+	talloc_free(mem_ctx);
+
+	Py_RETURN_NONE;
+}
+
 static PyObject *py_creds_guess(PyObject *self, PyObject *args)
 {
 	PyObject *py_lp_ctx = Py_None;
@@ -1279,6 +1315,11 @@ static PyMethodDef py_creds_methods[] = {
 		.ml_meth  = py_creds_set_krb_forwardable,
 		.ml_flags = METH_VARARGS,
 	},
+	{
+		.ml_name  = "set_conf",
+		.ml_meth  = py_creds_set_conf,
+		.ml_flags = METH_VARARGS,
+	},
 	{
 		.ml_name  = "guess",
 		.ml_meth  = py_creds_guess,
diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py
index e0a6248d37a..6187bded0b6 100644
--- a/python/samba/tests/credentials.py
+++ b/python/samba/tests/credentials.py
@@ -463,14 +463,47 @@ class CredentialsTests(samba.tests.TestCaseInTempDir):
         creds.set_smb_signing(credentials.SMB_SIGNING_REQUIRED)
         self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_REQUIRED)
 
+    def test_smb_signing_set_conf(self):
+        lp = samba.tests.env_loadparm()
+
+        creds = credentials.Credentials()
+        creds.set_conf(lp)
+        self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_DEFAULT)
+        creds.set_smb_signing(credentials.SMB_SIGNING_OFF)
+        self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_OFF)
+        creds.set_conf(lp)
+        self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_OFF)
+
     def test_smb_ipc_signing(self):
         creds = credentials.Credentials()
         self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED)
         creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF)
         self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF)
 
+    def test_smb_ipc_signing_set_conf(self):
+        lp = samba.tests.env_loadparm()
+
+        creds = credentials.Credentials()
+        creds.set_conf(lp)
+        self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED)
+        creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF)
+        self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF)
+        creds.set_conf(lp)
+        self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF)
+
     def test_smb_encryption(self):
         creds = credentials.Credentials()
         self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_DEFAULT)
         creds.set_smb_encryption(credentials.SMB_ENCRYPTION_REQUIRED)
         self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_REQUIRED)
+
+    def test_smb_encryption_set_conf(self):
+        lp = samba.tests.env_loadparm()
+
+        creds = credentials.Credentials()
+        creds.set_conf(lp)
+        self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_DEFAULT)
+        creds.set_smb_encryption(credentials.SMB_ENCRYPTION_OFF)
+        self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_OFF)
+        creds.set_conf(lp)
+        self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_OFF)
-- 
2.29.2


From 3f55ee05f024eacdd43fbbfb941703f8555df7c7 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 23 Jul 2020 08:14:23 +0200
Subject: [PATCH 020/104] auth:creds: Bump library version

We added new functions so bump the version.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 auth/credentials/wscript_build | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build
index 564a04fe8dd..1e3302e3e48 100644
--- a/auth/credentials/wscript_build
+++ b/auth/credentials/wscript_build
@@ -5,7 +5,7 @@ bld.SAMBA_LIBRARY('samba-credentials',
 	public_headers='credentials.h',
 	pc_files='samba-credentials.pc',
 	deps='LIBCRYPTO samba-errors events LIBCLI_AUTH samba-security CREDENTIALS_SECRETS CREDENTIALS_KRB5',
-	vnum='0.0.1'
+	vnum='0.1.0'
 	)
 
 bld.SAMBA_SUBSYSTEM('CREDENTIALS_KRB5',
-- 
2.29.2


From 492030e0e6179bdc0311e8d03b89b1cb01de1a3e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 27 May 2020 11:10:30 +0200
Subject: [PATCH 021/104] s3:lib: Use cli_credential_(get|set)_smb_signing()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/lib/util_cmdline.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c
index bc1f1c3ed25..6038ec11515 100644
--- a/source3/lib/util_cmdline.c
+++ b/source3/lib/util_cmdline.c
@@ -40,7 +40,6 @@ struct user_auth_info {
 	struct loadparm_context *lp_ctx;
 	bool got_username;
 	bool got_pass;
-	int signing_state;
 	bool smb_encrypt;
 	bool use_machine_account;
 	bool use_pw_nt_hash;
@@ -70,7 +69,6 @@ struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx)
 
 	cli_credentials_set_conf(result->creds, result->lp_ctx);
 
-	result->signing_state = SMB_SIGNING_DEFAULT;
 	return result;
 }
 
@@ -241,15 +239,23 @@ void set_cmdline_auth_info_password(struct user_auth_info *auth_info,
 bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info,
 					 const char *arg)
 {
-	auth_info->signing_state = smb_signing_setting_translate(arg);
+	enum smb_signing_setting signing_state =
+		smb_signing_setting_translate(arg);
+	bool ok;
 
-	return true;
+	ok = cli_credentials_set_smb_signing(auth_info->creds,
+					     signing_state,
+					     CRED_SPECIFIED);
+
+	return ok;
 }
 
 void set_cmdline_auth_info_signing_state_raw(struct user_auth_info *auth_info,
 					     int signing_state)
 {
-	auth_info->signing_state = signing_state;
+	cli_credentials_set_smb_signing(auth_info->creds,
+					signing_state,
+					CRED_SPECIFIED);
 }
 
 int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info)
@@ -257,7 +263,7 @@ int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info)
 	if (auth_info->smb_encrypt) {
 		return SMB_SIGNING_REQUIRED;
 	}
-	return auth_info->signing_state;
+	return cli_credentials_get_smb_signing(auth_info->creds);
 }
 
 void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, bool b)
-- 
2.29.2


From 6164c45feff5daf0e751526d1f7bd599c61b2a0e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:45:34 +0200
Subject: [PATCH 022/104] s3:lib: Set smb encryption also via cli creds API

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/lib/util_cmdline.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c
index 6038ec11515..9c9e2f0ac0f 100644
--- a/source3/lib/util_cmdline.c
+++ b/source3/lib/util_cmdline.c
@@ -377,6 +377,9 @@ void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info)
 /* This should only be used by lib/popt_common.c JRA */
 void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info)
 {
+	cli_credentials_set_smb_encryption(auth_info->creds,
+					   SMB_ENCRYPTION_REQUIRED,
+					   CRED_SPECIFIED);
 	auth_info->smb_encrypt = true;
 }
 
-- 
2.29.2


From ddb7926bba603afbc1a588d1b6da9f9a625881ac Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 13 Aug 2020 10:40:23 +0200
Subject: [PATCH 023/104] python: Remove unused sign argument from
 smb_connection()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 python/samba/netcmd/gpo.py | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index 1e2c2918ebe..ad60cda0690 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -382,13 +382,13 @@ def create_directory_hier(conn, remotedir):
         if not conn.chkpath(path):
             conn.mkdir(path)
 
-def smb_connection(dc_hostname, service, lp, creds, sign=False):
+def smb_connection(dc_hostname, service, lp, creds):
     # SMB connect to DC
     try:
         # the SMB bindings rely on having a s3 loadparm
         s3_lp = s3param.get_context()
         s3_lp.load(lp.configfile)
-        conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=sign)
+        conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=True)
     except Exception:
         raise CommandError("Error connecting to '%s' using SMB" % dc_hostname)
     return conn
@@ -998,7 +998,7 @@ class cmd_fetch(GPOCommand):
 
         # SMB connect to DC
         conn = smb_connection(dc_hostname, service, lp=self.lp,
-                              creds=self.creds, sign=True)
+                              creds=self.creds)
 
         # Copy GPT
         tmpdir, gpodir = self.construct_tmpdir(tmpdir, gpo)
@@ -1629,8 +1629,7 @@ class cmd_admxload(Command):
         conn = smb_connection(dc_hostname,
                               'sysvol',
                               lp=self.lp,
-                              creds=self.creds,
-                              sign=True)
+                              creds=self.creds)
 
         smb_dir = '\\'.join([self.lp.get('realm').lower(),
                              'Policies', 'PolicyDefinitions'])
-- 
2.29.2


From 8683eacfb9c053115a84be025bbd64471c55d1c8 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 3 Jun 2020 14:02:37 +0200
Subject: [PATCH 024/104] python: Set smb signing via the creds API

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 python/samba/gpclass.py              |  7 +++++++
 python/samba/netcmd/domain_backup.py | 10 +++++++++-
 python/samba/netcmd/gpo.py           |  6 ++++++
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index cc574e12a42..1781a55a618 100644
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -38,6 +38,7 @@ from tempfile import NamedTemporaryFile
 from samba.dcerpc import preg
 from samba.dcerpc import misc
 from samba.ndr import ndr_pack, ndr_unpack
+from samba.credentials import SMB_SIGNING_REQUIRED
 
 try:
     from enum import Enum
@@ -421,7 +422,13 @@ def check_refresh_gpo_list(dc_hostname, lp, creds, gpos):
     # the SMB bindings rely on having a s3 loadparm
     s3_lp = s3param.get_context()
     s3_lp.load(lp.configfile)
+
+    # Force signing for the connection
+    saved_signing_state = creds.get_smb_signing()
+    creds.set_smb_signing(SMB_SIGNING_REQUIRED)
     conn = libsmb.Conn(dc_hostname, 'sysvol', lp=s3_lp, creds=creds, sign=True)
+    # Reset signing state
+    creds.set_smb_signing(saved_signing_state)
     cache_path = lp.cache_path('gpo_cache')
     for gpo in gpos:
         if not gpo.file_sys_path:
diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py
index a3dc7fb454f..a9e0ba5bc67 100644
--- a/python/samba/netcmd/domain_backup.py
+++ b/python/samba/netcmd/domain_backup.py
@@ -54,6 +54,7 @@ from subprocess import CalledProcessError
 from samba import sites
 from samba.dsdb import _dsdb_load_udv_v2
 from samba.ndr import ndr_pack
+from samba.credentials import SMB_SIGNING_REQUIRED
 
 
 # work out a SID (based on a free RID) to use when the domain gets restored.
@@ -115,7 +116,14 @@ def smb_sysvol_conn(server, lp, creds):
     # the SMB bindings rely on having a s3 loadparm
     s3_lp = s3param.get_context()
     s3_lp.load(lp.configfile)
-    return libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds, sign=True)
+
+    # Force signing for the connection
+    saved_signing_state = creds.get_smb_signing()
+    creds.set_smb_signing(SMB_SIGNING_REQUIRED)
+    conn = libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds, sign=True)
+    # Reset signing state
+    creds.set_smb_signing(saved_signing_state)
+    return conn
 
 
 def get_timestamp():
diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index ad60cda0690..0f2f6520fc3 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -62,6 +62,7 @@ from samba.gp_parse.gp_csv import GPAuditCsvParser
 from samba.gp_parse.gp_inf import GptTmplInfParser
 from samba.gp_parse.gp_aas import GPAasParser
 from samba import param
+from samba.credentials import SMB_SIGNING_REQUIRED
 
 
 def attr_default(msg, attrname, default):
@@ -384,6 +385,9 @@ def create_directory_hier(conn, remotedir):
 
 def smb_connection(dc_hostname, service, lp, creds):
     # SMB connect to DC
+    # Force signing for the smb connection
+    saved_signing_state = creds.get_smb_signing()
+    creds.set_smb_signing(SMB_SIGNING_REQUIRED)
     try:
         # the SMB bindings rely on having a s3 loadparm
         s3_lp = s3param.get_context()
@@ -391,6 +395,8 @@ def smb_connection(dc_hostname, service, lp, creds):
         conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=True)
     except Exception:
         raise CommandError("Error connecting to '%s' using SMB" % dc_hostname)
+    # Reset signing state
+    creds.set_smb_signing(saved_signing_state)
     return conn
 
 
-- 
2.29.2


From 86212ac5fb8d5f0710f23dde362dc35d908e3047 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 17:22:12 +0200
Subject: [PATCH 025/104] s3:libsmb: Introduce CLI_FULL_CONNECTION_IPC

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 examples/winexe/winexe.c                    | 2 +-
 source3/include/client.h                    | 1 +
 source3/libnet/libnet_join.c                | 6 +++---
 source3/libsmb/cliconnect.c                 | 3 ++-
 source3/rpc_server/spoolss/srv_spoolss_nt.c | 4 +++-
 source3/rpcclient/cmd_spoolss.c             | 2 +-
 source3/rpcclient/rpcclient.c               | 2 +-
 source3/utils/mdfind.c                      | 2 +-
 source3/utils/net_ads.c                     | 3 ++-
 source3/utils/net_util.c                    | 9 +++++++--
 source3/utils/netlookup.c                   | 4 +++-
 11 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c
index fc6b15f8e52..bb9c27e2e6d 100644
--- a/examples/winexe/winexe.c
+++ b/examples/winexe/winexe.c
@@ -1919,7 +1919,7 @@ int main(int argc, const char *argv[])
 		"IPC$",
 		"?????",
 		options.credentials,
-		0,
+		CLI_FULL_CONNECTION_IPC,
 		0);
 
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/include/client.h b/source3/include/client.h
index 6a3b1b02ff3..19a738900b7 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -121,5 +121,6 @@ struct file_info {
 #define CLI_FULL_CONNECTION_FORCE_ASCII 0x0100
 #define CLI_FULL_CONNECTION_FORCE_SMB1 0x0400
 #define CLI_FULL_CONNECTION_DISABLE_SMB1 0x0800
+#define CLI_FULL_CONNECTION_IPC          0x1000
 
 #endif /* _CLIENT_H */
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 34938603606..392e3eff74f 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1068,7 +1068,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc,
 	bool use_ccache = false;
 	bool pw_nt_hash = false;
 	struct cli_credentials *creds = NULL;
-	int flags = 0;
+	int flags = CLI_FULL_CONNECTION_IPC;
 	NTSTATUS status;
 
 	if (use_kerberos && pass) {
@@ -1684,7 +1684,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
 	struct netlogon_creds_CredentialState *creds = NULL;
 	uint32_t netlogon_flags = 0;
 	NTSTATUS status;
-	int flags = 0;
+	int flags = CLI_FULL_CONNECTION_IPC;
 
 	if (!dc_name) {
 		TALLOC_FREE(frame);
@@ -1734,7 +1734,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
 						   NULL, 0,
 						   "IPC$", "IPC",
 						   anon_creds,
-						   0,
+						   flags,
 						   SMB_SIGNING_OFF);
 	}
 
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 1fb1f0127b9..f20146378e3 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2788,7 +2788,7 @@ static struct tevent_req *cli_start_connection_send(
 	}
 	state->ev = ev;
 
-	if (signing_state == SMB_SIGNING_IPC_DEFAULT) {
+	if (flags & CLI_FULL_CONNECTION_IPC) {
 		state->min_protocol = lp_client_ipc_min_protocol();
 		state->max_protocol = lp_client_ipc_max_protocol();
 	} else {
@@ -3673,6 +3673,7 @@ struct cli_state *get_ipc_connect(char *server,
 	uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK;
 
 	flags |= CLI_FULL_CONNECTION_FORCE_SMB1;
+	flags |= CLI_FULL_CONNECTION_IPC;
 
 	nt_status = cli_full_connection_creds(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
 					get_cmdline_auth_info_creds(user_info),
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index 10c1b1d54f2..f578f1c4131 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -2482,7 +2482,9 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct c
 	/* setup the connection */
 	ret = cli_full_connection_creds( pp_cli, lp_netbios_name(), remote_machine,
 		&rm_addr, 0, "IPC$", "IPC",
-		anon_creds, 0, SMB_SIGNING_OFF);
+		anon_creds,
+		CLI_FULL_CONNECTION_IPC,
+		SMB_SIGNING_OFF);
 	TALLOC_FREE(anon_creds);
 	if ( !NT_STATUS_IS_OK( ret ) ) {
 		DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index a7e0c673a65..7198a451ab7 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -3537,7 +3537,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
 				"IPC$", "IPC",
 				get_cmdline_auth_info_creds(
 					popt_get_cmdline_auth_info()),
-				0, /* flags */
+				CLI_FULL_CONNECTION_IPC,
 				get_cmdline_auth_info_signing_state(
 					popt_get_cmdline_auth_info()));
 
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 67a1066fc15..c86474d08f1 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -1019,7 +1019,7 @@ out_free:
 	static int		opt_port = 0;
 	int result = 0;
 	TALLOC_CTX *frame = talloc_stackframe();
-	uint32_t flags = 0;
+	uint32_t flags = CLI_FULL_CONNECTION_IPC;
 	struct dcerpc_binding *binding = NULL;
 	enum dcerpc_transport_t transport;
 	uint32_t bflags = 0;
diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c
index 2f952c29b4f..a3c879e75fb 100644
--- a/source3/utils/mdfind.c
+++ b/source3/utils/mdfind.c
@@ -70,7 +70,7 @@ int main(int argc, char **argv)
 	const char *mds_query = NULL;
 	struct cli_state *cli = NULL;
 	char *basepath = NULL;
-	uint32_t flags = 0;
+	uint32_t flags = CLI_FULL_CONNECTION_IPC;
 	int signing_state = SMB_SIGNING_IPC_DEFAULT;
 	uint64_t *cnids = NULL;
 	size_t ncnids;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index e5db844c2f2..28ef6dc9974 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -2437,7 +2437,8 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
 	nt_status = cli_full_connection_creds(&cli, lp_netbios_name(), servername,
 					&server_ss, 0,
 					"IPC$", "IPC",
-					creds, 0,
+					creds,
+					CLI_FULL_CONNECTION_IPC,
 					SMB_SIGNING_IPC_DEFAULT);
 
 	if (NT_STATUS_IS_ERR(nt_status)) {
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index c566ecc9000..d01b2d8c771 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -110,6 +110,7 @@ NTSTATUS connect_to_service(struct net_context *c,
 	NTSTATUS nt_status;
 	enum smb_signing_setting signing_setting = SMB_SIGNING_DEFAULT;
 	struct cli_credentials *creds = NULL;
+	int flags = 0;
 
 	creds = net_context_creds(c, c);
 	if (creds == NULL) {
@@ -119,12 +120,14 @@ NTSTATUS connect_to_service(struct net_context *c,
 
 	if (strequal(service_type, "IPC")) {
 		signing_setting = SMB_SIGNING_IPC_DEFAULT;
+		flags |= CLI_FULL_CONNECTION_IPC;
 	}
 
 	nt_status = cli_full_connection_creds(cli_ctx, NULL, server_name,
 					server_ss, c->opt_port,
 					service_name, service_type,
-					creds, 0,
+					creds,
+					flags,
 					signing_setting);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		d_fprintf(stderr, _("Could not connect to server %s\n"),
@@ -195,7 +198,9 @@ NTSTATUS connect_to_ipc_anonymous(struct net_context *c,
 	nt_status = cli_full_connection_creds(cli_ctx, c->opt_requester_name,
 					server_name, server_ss, c->opt_port,
 					"IPC$", "IPC",
-					anon_creds, 0, SMB_SIGNING_OFF);
+					anon_creds,
+					CLI_FULL_CONNECTION_IPC,
+					SMB_SIGNING_OFF);
 
 	if (NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
diff --git a/source3/utils/netlookup.c b/source3/utils/netlookup.c
index 6cea2ee306c..2241beb331f 100644
--- a/source3/utils/netlookup.c
+++ b/source3/utils/netlookup.c
@@ -98,7 +98,9 @@ static struct con_struct *create_cs(struct net_context *c,
 	nt_status = cli_full_connection_creds(&cs->cli, lp_netbios_name(), lp_netbios_name(),
 					&loopback_ss, 0,
 					"IPC$", "IPC",
-					anon_creds, 0, SMB_SIGNING_OFF);
+					anon_creds,
+					CLI_FULL_CONNECTION_IPC,
+					SMB_SIGNING_OFF);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status)));
-- 
2.29.2


From 834dae6a34aaef7dccfb84821ec3fa7013b07d15 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 17:29:25 +0200
Subject: [PATCH 026/104] s3:pylibsmb: Add ipc=True support for
 CLI_FULL_CONNECTION_IPC

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/libsmb/pylibsmb.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c
index 3fcc3424a57..3579a040830 100644
--- a/source3/libsmb/pylibsmb.c
+++ b/source3/libsmb/pylibsmb.c
@@ -445,6 +445,8 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	int signing_state = SMB_SIGNING_DEFAULT;
 	PyObject *py_force_smb1 = Py_False;
 	bool force_smb1 = false;
+	PyObject *py_ipc = Py_False;
+	bool use_ipc = false;
 	struct tevent_req *req;
 	bool ret;
 	int flags = 0;
@@ -452,6 +454,7 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	static const char *kwlist[] = {
 		"host", "share", "lp", "creds",
 		"multi_threaded", "sign", "force_smb1",
+		"ipc",
 		NULL
 	};
 
@@ -462,12 +465,13 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	}
 
 	ret = ParseTupleAndKeywords(
-		args, kwds, "ssO|O!OOO", kwlist,
+		args, kwds, "ssO|O!OOOO", kwlist,
 		&host, &share, &py_lp,
 		py_type_Credentials, &creds,
 		&py_multi_threaded,
 		&py_sign,
-		&py_force_smb1);
+		&py_force_smb1,
+		&py_ipc);
 
 	Py_DECREF(py_type_Credentials);
 
@@ -493,6 +497,11 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 		flags = CLI_FULL_CONNECTION_FORCE_SMB1;
 	}
 
+	use_ipc = PyObject_IsTrue(py_ipc);
+	if (use_ipc) {
+		flags |= CLI_FULL_CONNECTION_IPC;
+	}
+
 	if (multi_threaded) {
 #ifdef HAVE_PTHREAD
 		ret = py_cli_state_setup_mt_ev(self);
-- 
2.29.2


From 072dfd83ee6513658e0ec818fb548f70648d6a41 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 24 Jul 2020 09:47:11 +0200
Subject: [PATCH 027/104] python:tests: Mark libsmb connection as an IPC
 connection

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 python/samba/tests/dcerpc/raw_testcase.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py
index ba7440df13b..2c028d381db 100644
--- a/python/samba/tests/dcerpc/raw_testcase.py
+++ b/python/samba/tests/dcerpc/raw_testcase.py
@@ -43,7 +43,7 @@ class smb_pipe_socket(object):
         lp3 = s3param.get_context()
         lp3.load(lp.configfile)
         self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3,
-                                   creds=creds, sign=True)
+                                   creds=creds, ipc=True, sign=True)
         self.smbfid = self.smbconn.create(pipename,
                                           DesiredAccess=0x12019f,
                                           ShareAccess=0x7,
-- 
2.29.2


From ceb25f6cb4fd07cd736085030a02aefbcb012e34 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 17 Aug 2020 12:52:39 +0200
Subject: [PATCH 028/104] python:tests: Set smb ipc signing via the creds API

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 python/samba/tests/dcerpc/raw_testcase.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py
index 2c028d381db..d6f5de7440a 100644
--- a/python/samba/tests/dcerpc/raw_testcase.py
+++ b/python/samba/tests/dcerpc/raw_testcase.py
@@ -36,14 +36,18 @@ from samba.ntstatus import (
 from samba import NTSTATUSError
 from samba.samba3 import param as s3param
 from samba.samba3 import libsmb_samba_internal as libsmb
+from samba.credentials import SMB_SIGNING_REQUIRED
 
 class smb_pipe_socket(object):
 
     def __init__(self, target_hostname, pipename, creds, impersonation_level, lp):
         lp3 = s3param.get_context()
         lp3.load(lp.configfile)
+        saved_signing_state = creds.get_smb_ipc_signing()
+        creds.set_smb_ipc_signing(SMB_SIGNING_REQUIRED)
         self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3,
                                    creds=creds, ipc=True, sign=True)
+        creds.set_smb_ipc_signing(saved_signing_state)
         self.smbfid = self.smbconn.create(pipename,
                                           DesiredAccess=0x12019f,
                                           ShareAccess=0x7,
-- 
2.29.2


From d3fe919fa5b952d075353f0d5c5366cabd5ef976 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 17:59:19 +0200
Subject: [PATCH 029/104] s3:libsmb: Use 'enum smb_signing_setting' in
 cliconnect.c

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/libsmb/cliconnect.c | 14 +++++++-------
 source3/libsmb/proto.h      | 10 +++++-----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index f20146378e3..bb20aa59385 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -2631,7 +2631,7 @@ static NTSTATUS cli_connect_sock_recv(struct tevent_req *req,
 
 struct cli_connect_nb_state {
 	const char *desthost;
-	int signing_state;
+	enum smb_signing_setting signing_state;
 	int flags;
 	struct cli_state *cli;
 };
@@ -2642,7 +2642,7 @@ static struct tevent_req *cli_connect_nb_send(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 	const char *host, const struct sockaddr_storage *dest_ss,
 	uint16_t port, int name_type, const char *myname,
-	int signing_state, int flags)
+	enum smb_signing_setting signing_state, int flags)
 {
 	struct tevent_req *req, *subreq;
 	struct cli_connect_nb_state *state;
@@ -2727,7 +2727,7 @@ static NTSTATUS cli_connect_nb_recv(struct tevent_req *req,
 
 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
 			uint16_t port, int name_type, const char *myname,
-			int signing_state, int flags, struct cli_state **pcli)
+			enum smb_signing_setting signing_state, int flags, struct cli_state **pcli)
 {
 	struct tevent_context *ev;
 	struct tevent_req *req;
@@ -2776,7 +2776,7 @@ static struct tevent_req *cli_start_connection_send(
 	TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 	const char *my_name, const char *dest_host,
 	const struct sockaddr_storage *dest_ss, int port,
-	int signing_state, int flags)
+	enum smb_signing_setting signing_state, int flags)
 {
 	struct tevent_req *req, *subreq;
 	struct cli_start_connection_state *state;
@@ -2881,7 +2881,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli,
 			      const char *my_name, 
 			      const char *dest_host, 
 			      const struct sockaddr_storage *dest_ss, int port,
-			      int signing_state, int flags)
+			      enum smb_signing_setting signing_state, int flags)
 {
 	struct tevent_context *ev;
 	struct tevent_req *req;
@@ -3361,7 +3361,7 @@ struct tevent_req *cli_full_connection_creds_send(
 	const struct sockaddr_storage *dest_ss, int port,
 	const char *service, const char *service_type,
 	struct cli_credentials *creds,
-	int flags, int signing_state)
+	int flags, enum smb_signing_setting signing_state)
 {
 	struct tevent_req *req, *subreq;
 	struct cli_full_connection_creds_state *state;
@@ -3520,7 +3520,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
 				   const char *service, const char *service_type,
 				   struct cli_credentials *creds,
 				   int flags,
-				   int signing_state)
+				   enum smb_signing_setting signing_state)
 {
 	struct tevent_context *ev;
 	struct tevent_req *req;
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index d214cdabca4..995187e21b4 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -86,12 +86,12 @@ NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share,
 NTSTATUS cli_tdis(struct cli_state *cli);
 NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss,
 			uint16_t port, int name_type, const char *myname,
-			int signing_state, int flags, struct cli_state **pcli);
+			enum smb_signing_setting signing_state, int flags, struct cli_state **pcli);
 NTSTATUS cli_start_connection(struct cli_state **output_cli,
 			      const char *my_name,
 			      const char *dest_host,
 			      const struct sockaddr_storage *dest_ss, int port,
-			      int signing_state, int flags);
+			      enum smb_signing_setting signing_state, int flags);
 NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli,
 				   struct cli_credentials *creds);
 struct tevent_req *cli_full_connection_creds_send(
@@ -100,7 +100,7 @@ struct tevent_req *cli_full_connection_creds_send(
 	const struct sockaddr_storage *dest_ss, int port,
 	const char *service, const char *service_type,
 	struct cli_credentials *creds,
-	int flags, int signing_state);
+	int flags, enum smb_signing_setting signing_state);
 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
 					struct cli_state **output_cli);
 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
@@ -110,7 +110,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
 				   const char *service, const char *service_type,
 				   struct cli_credentials *creds,
 				   int flags,
-				   int signing_state);
+				   enum smb_signing_setting signing_state);
 NTSTATUS cli_raw_tcon(struct cli_state *cli,
 		      const char *service, const char *pass, const char *dev,
 		      uint16_t *max_xmit, uint16_t *tid);
@@ -177,7 +177,7 @@ extern struct GUID cli_state_client_guid;
 struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
 				   int fd,
 				   const char *remote_name,
-				   int signing_state,
+				   enum smb_signing_setting signing_state,
 				   int flags);
 void cli_nt_pipes_close(struct cli_state *cli);
 void cli_shutdown(struct cli_state *cli);
-- 
2.29.2


From 0ec1b432bf807efe37fdedf346724e787742e3aa Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 18:11:31 +0200
Subject: [PATCH 030/104] s3:client: Turn off smb signing for message op

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 python/samba/gpclass.py                   |  2 +-
 python/samba/netcmd/domain_backup.py      |  2 +-
 python/samba/netcmd/gpo.py                |  2 +-
 python/samba/tests/dcerpc/raw_testcase.py |  2 +-
 source3/client/client.c                   |  5 ++++-
 source3/libsmb/pylibsmb.c                 | 20 +++++++++-----------
 6 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 1781a55a618..2c00f5349a0 100644
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -426,7 +426,7 @@ def check_refresh_gpo_list(dc_hostname, lp, creds, gpos):
     # Force signing for the connection
     saved_signing_state = creds.get_smb_signing()
     creds.set_smb_signing(SMB_SIGNING_REQUIRED)
-    conn = libsmb.Conn(dc_hostname, 'sysvol', lp=s3_lp, creds=creds, sign=True)
+    conn = libsmb.Conn(dc_hostname, 'sysvol', lp=s3_lp, creds=creds)
     # Reset signing state
     creds.set_smb_signing(saved_signing_state)
     cache_path = lp.cache_path('gpo_cache')
diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py
index a9e0ba5bc67..2977b071ec3 100644
--- a/python/samba/netcmd/domain_backup.py
+++ b/python/samba/netcmd/domain_backup.py
@@ -120,7 +120,7 @@ def smb_sysvol_conn(server, lp, creds):
     # Force signing for the connection
     saved_signing_state = creds.get_smb_signing()
     creds.set_smb_signing(SMB_SIGNING_REQUIRED)
-    conn = libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds, sign=True)
+    conn = libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds)
     # Reset signing state
     creds.set_smb_signing(saved_signing_state)
     return conn
diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index 0f2f6520fc3..bbaa0c17881 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -392,7 +392,7 @@ def smb_connection(dc_hostname, service, lp, creds):
         # the SMB bindings rely on having a s3 loadparm
         s3_lp = s3param.get_context()
         s3_lp.load(lp.configfile)
-        conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=True)
+        conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds)
     except Exception:
         raise CommandError("Error connecting to '%s' using SMB" % dc_hostname)
     # Reset signing state
diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py
index d6f5de7440a..34785e2a2a7 100644
--- a/python/samba/tests/dcerpc/raw_testcase.py
+++ b/python/samba/tests/dcerpc/raw_testcase.py
@@ -46,7 +46,7 @@ class smb_pipe_socket(object):
         saved_signing_state = creds.get_smb_ipc_signing()
         creds.set_smb_ipc_signing(SMB_SIGNING_REQUIRED)
         self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3,
-                                   creds=creds, ipc=True, sign=True)
+                                   creds=creds, ipc=True)
         creds.set_smb_ipc_signing(saved_signing_state)
         self.smbfid = self.smbconn.create(pipename,
                                           DesiredAccess=0x12019f,
diff --git a/source3/client/client.c b/source3/client/client.c
index 8c7ceb644aa..56309efcea7 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -6164,7 +6164,10 @@ static int do_message_op(struct user_auth_info *a_info)
 
 	status = cli_connect_nb(desthost, have_ip ? &dest_ss : NULL,
 				port ? port : NBT_SMB_PORT, name_type,
-				lp_netbios_name(), SMB_SIGNING_DEFAULT, 0, &cli);
+				lp_netbios_name(),
+				SMB_SIGNING_OFF,
+				0,
+				&cli);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status));
 		return 1;
diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c
index 3579a040830..f8a4d56cf53 100644
--- a/source3/libsmb/pylibsmb.c
+++ b/source3/libsmb/pylibsmb.c
@@ -440,9 +440,7 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	PyObject *py_lp = Py_None;
 	PyObject *py_multi_threaded = Py_False;
 	bool multi_threaded = false;
-	PyObject *py_sign = Py_False;
-	bool sign = false;
-	int signing_state = SMB_SIGNING_DEFAULT;
+	enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
 	PyObject *py_force_smb1 = Py_False;
 	bool force_smb1 = false;
 	PyObject *py_ipc = Py_False;
@@ -453,7 +451,7 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 
 	static const char *kwlist[] = {
 		"host", "share", "lp", "creds",
-		"multi_threaded", "sign", "force_smb1",
+		"multi_threaded", "force_smb1",
 		"ipc",
 		NULL
 	};
@@ -465,11 +463,10 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	}
 
 	ret = ParseTupleAndKeywords(
-		args, kwds, "ssO|O!OOOO", kwlist,
+		args, kwds, "ssO|O!OOO", kwlist,
 		&host, &share, &py_lp,
 		py_type_Credentials, &creds,
 		&py_multi_threaded,
-		&py_sign,
 		&py_force_smb1,
 		&py_ipc);
 
@@ -480,13 +477,8 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	}
 
 	multi_threaded = PyObject_IsTrue(py_multi_threaded);
-	sign = PyObject_IsTrue(py_sign);
 	force_smb1 = PyObject_IsTrue(py_force_smb1);
 
-	if (sign) {
-		signing_state = SMB_SIGNING_REQUIRED;
-	}
-
 	if (force_smb1) {
 		/*
 		 * As most of the cli_*_send() function
@@ -532,6 +524,12 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 		cli_creds = PyCredentials_AsCliCredentials(creds);
 	}
 
+	if (use_ipc) {
+		signing_state = cli_credentials_get_smb_ipc_signing(cli_creds);
+	} else {
+		signing_state = cli_credentials_get_smb_signing(cli_creds);
+	}
+
 	req = cli_full_connection_creds_send(
 		NULL, self->ev, "myname", host, NULL, 0, share, "?????",
 		cli_creds, flags, signing_state);
-- 
2.29.2


From dd6a89dd02e675e1b836042e4a4dec31667ac58c Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 28 May 2020 18:20:02 +0200
Subject: [PATCH 031/104] s3:libsmb: Remove signing_state from
 cli_full_connection_creds_send()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/libsmb/cliconnect.c | 11 +++++++++--
 source3/libsmb/proto.h      |  2 +-
 source3/libsmb/pylibsmb.c   |  9 +--------
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index bb20aa59385..0ff9c283e39 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -3361,10 +3361,11 @@ struct tevent_req *cli_full_connection_creds_send(
 	const struct sockaddr_storage *dest_ss, int port,
 	const char *service, const char *service_type,
 	struct cli_credentials *creds,
-	int flags, enum smb_signing_setting signing_state)
+	int flags)
 {
 	struct tevent_req *req, *subreq;
 	struct cli_full_connection_creds_state *state;
+	enum smb_signing_setting signing_state;
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct cli_full_connection_creds_state);
@@ -3379,6 +3380,12 @@ struct tevent_req *cli_full_connection_creds_send(
 	state->creds = creds;
 	state->flags = flags;
 
+	if (flags & CLI_FULL_CONNECTION_IPC) {
+		signing_state = cli_credentials_get_smb_ipc_signing(creds);
+	} else {
+		signing_state = cli_credentials_get_smb_signing(creds);
+	}
+
 	subreq = cli_start_connection_send(
 		state, ev, my_name, dest_host, dest_ss, port,
 		signing_state, flags);
@@ -3532,7 +3539,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
 	}
 	req = cli_full_connection_creds_send(
 		ev, ev, my_name, dest_host, dest_ss, port, service,
-		service_type, creds, flags, signing_state);
+		service_type, creds, flags);
 	if (req == NULL) {
 		goto fail;
 	}
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 995187e21b4..bef04d32638 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -100,7 +100,7 @@ struct tevent_req *cli_full_connection_creds_send(
 	const struct sockaddr_storage *dest_ss, int port,
 	const char *service, const char *service_type,
 	struct cli_credentials *creds,
-	int flags, enum smb_signing_setting signing_state);
+	int flags);
 NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req,
 					struct cli_state **output_cli);
 NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c
index f8a4d56cf53..c7a2d73afcb 100644
--- a/source3/libsmb/pylibsmb.c
+++ b/source3/libsmb/pylibsmb.c
@@ -440,7 +440,6 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 	PyObject *py_lp = Py_None;
 	PyObject *py_multi_threaded = Py_False;
 	bool multi_threaded = false;
-	enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
 	PyObject *py_force_smb1 = Py_False;
 	bool force_smb1 = false;
 	PyObject *py_ipc = Py_False;
@@ -524,15 +523,9 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args,
 		cli_creds = PyCredentials_AsCliCredentials(creds);
 	}
 
-	if (use_ipc) {
-		signing_state = cli_credentials_get_smb_ipc_signing(cli_creds);
-	} else {
-		signing_state = cli_credentials_get_smb_signing(cli_creds);
-	}
-
 	req = cli_full_connection_creds_send(
 		NULL, self->ev, "myname", host, NULL, 0, share, "?????",
-		cli_creds, flags, signing_state);
+		cli_creds, flags);
 	if (!py_tevent_req_wait_exc(self, req)) {
 		return -1;
 	}
-- 
2.29.2


From b31e224159fe25e8cf84e7d2ef8bc53934ddd209 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 4 Jun 2020 14:59:14 +0200
Subject: [PATCH 032/104] s3:libsmb: Remove signing_state from
 cli_full_connection_creds()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 examples/fuse/smb2mount.c                   |  3 +--
 examples/winexe/winexe.c                    |  4 +---
 source3/libnet/libnet_join.c                |  9 +++------
 source3/libsmb/cliconnect.c                 |  6 ++----
 source3/libsmb/libsmb_server.c              |  8 +-------
 source3/libsmb/proto.h                      |  3 +--
 source3/rpc_server/spoolss/srv_spoolss_nt.c |  3 +--
 source3/rpcclient/cmd_spoolss.c             |  5 +----
 source3/rpcclient/rpcclient.c               |  3 +--
 source3/torture/locktest2.c                 | 11 +++++++++--
 source3/torture/torture.c                   |  6 ++----
 source3/utils/mdfind.c                      |  3 +--
 source3/utils/net_ads.c                     |  3 +--
 source3/utils/net_util.c                    |  8 ++------
 source3/utils/netlookup.c                   |  3 +--
 source3/utils/smbcacls.c                    |  3 +--
 source3/utils/smbcquotas.c                  |  4 +---
 17 files changed, 30 insertions(+), 55 deletions(-)

diff --git a/examples/fuse/smb2mount.c b/examples/fuse/smb2mount.c
index ea1d9a11e0b..6206c3a9701 100644
--- a/examples/fuse/smb2mount.c
+++ b/examples/fuse/smb2mount.c
@@ -37,8 +37,7 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info,
 				NULL, port,
 				share, "?????",
 				get_cmdline_auth_info_creds(auth_info),
-				flags,
-				get_cmdline_auth_info_signing_state(auth_info));
+				flags);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DBG_ERR("cli_full_connection failed! (%s)\n",
 			nt_errstr(nt_status));
diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c
index bb9c27e2e6d..03e7ec85198 100644
--- a/examples/winexe/winexe.c
+++ b/examples/winexe/winexe.c
@@ -360,7 +360,6 @@ static NTSTATUS winexe_svc_upload(
 		"ADMIN$",
 		"?????",
 		credentials,
-		0,
 		0);
 	if (!NT_STATUS_IS_OK(status)) {
 		DBG_WARNING("cli_full_connection_creds failed: %s\n",
@@ -1919,8 +1918,7 @@ int main(int argc, const char *argv[])
 		"IPC$",
 		"?????",
 		options.credentials,
-		CLI_FULL_CONNECTION_IPC,
-		0);
+		CLI_FULL_CONNECTION_IPC);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DBG_WARNING("cli_full_connection_creds failed: %s\n",
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 392e3eff74f..f3bf27e6c00 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1095,8 +1095,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc,
 					   NULL, 0,
 					   "IPC$", "IPC",
 					   creds,
-					   flags,
-					   SMB_SIGNING_IPC_DEFAULT);
+					   flags);
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(frame);
 		return status;
@@ -1716,8 +1715,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
 					   NULL, 0,
 					   "IPC$", "IPC",
 					   cli_creds,
-					   flags,
-					   SMB_SIGNING_IPC_DEFAULT);
+					   flags);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		struct cli_credentials *anon_creds = NULL;
@@ -1734,8 +1732,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
 						   NULL, 0,
 						   "IPC$", "IPC",
 						   anon_creds,
-						   flags,
-						   SMB_SIGNING_OFF);
+						   flags);
 	}
 
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 0ff9c283e39..b24743d789b 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -3526,8 +3526,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
 				   const struct sockaddr_storage *dest_ss, int port,
 				   const char *service, const char *service_type,
 				   struct cli_credentials *creds,
-				   int flags,
-				   enum smb_signing_setting signing_state)
+				   int flags)
 {
 	struct tevent_context *ev;
 	struct tevent_req *req;
@@ -3684,8 +3683,7 @@ struct cli_state *get_ipc_connect(char *server,
 
 	nt_status = cli_full_connection_creds(&cli, NULL, server, server_ss, 0, "IPC$", "IPC",
 					get_cmdline_auth_info_creds(user_info),
-					flags,
-					SMB_SIGNING_DEFAULT);
+					flags);
 
 	if (NT_STATUS_IS_OK(nt_status)) {
 		return cli;
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 3d1cd602f6c..33dc8419deb 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -785,7 +785,6 @@ SMBC_attr_server(TALLOC_CTX *ctx,
                                    pp_workgroup, pp_username, pp_password);
         if (!ipc_srv) {
 		struct cli_credentials *creds = NULL;
-		int signing_state = SMB_SIGNING_DEFAULT;
 
                 /* We didn't find a cached connection.  Get the password */
 		if (!*pp_password || (*pp_password)[0] == '\0') {
@@ -812,16 +811,11 @@ SMBC_attr_server(TALLOC_CTX *ctx,
 			return NULL;
 		}
 
-		if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) {
-			signing_state = SMB_SIGNING_REQUIRED;
-		}
-
 		nt_status = cli_full_connection_creds(&ipc_cli,
 						lp_netbios_name(), server,
 						NULL, 0, "IPC$", "?????",
 						creds,
-						flags,
-						signing_state);
+						flags);
                 if (! NT_STATUS_IS_OK(nt_status)) {
 			TALLOC_FREE(creds);
                         DEBUG(1,("cli_full_connection failed! (%s)\n",
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index bef04d32638..850cf12c8a6 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -109,8 +109,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli,
 				   const struct sockaddr_storage *dest_ss, int port,
 				   const char *service, const char *service_type,
 				   struct cli_credentials *creds,
-				   int flags,
-				   enum smb_signing_setting signing_state);
+				   int flags);
 NTSTATUS cli_raw_tcon(struct cli_state *cli,
 		      const char *service, const char *pass, const char *dev,
 		      uint16_t *max_xmit, uint16_t *tid);
diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c
index f578f1c4131..906fab2adb5 100644
--- a/source3/rpc_server/spoolss/srv_spoolss_nt.c
+++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c
@@ -2483,8 +2483,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct c
 	ret = cli_full_connection_creds( pp_cli, lp_netbios_name(), remote_machine,
 		&rm_addr, 0, "IPC$", "IPC",
 		anon_creds,
-		CLI_FULL_CONNECTION_IPC,
-		SMB_SIGNING_OFF);
+		CLI_FULL_CONNECTION_IPC);
 	TALLOC_FREE(anon_creds);
 	if ( !NT_STATUS_IS_OK( ret ) ) {
 		DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index 7198a451ab7..02889a0a666 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -3537,10 +3537,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli,
 				"IPC$", "IPC",
 				get_cmdline_auth_info_creds(
 					popt_get_cmdline_auth_info()),
-				CLI_FULL_CONNECTION_IPC,
-				get_cmdline_auth_info_signing_state(
-					popt_get_cmdline_auth_info()));
-
+				CLI_FULL_CONNECTION_IPC);
 	if ( !NT_STATUS_IS_OK(nt_status) )
 		return WERR_GEN_FAILURE;
 
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index c86474d08f1..2ead6cc7ba5 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -1206,8 +1206,7 @@ out_free:
 					"IPC$", "IPC",
 					get_cmdline_auth_info_creds(
 						popt_get_cmdline_auth_info()),
-					flags,
-					SMB_SIGNING_IPC_DEFAULT);
+					flags);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("Cannot connect to server.  Error was %s\n", nt_errstr(nt_status)));
diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c
index 84c335f959f..92ddb7629b9 100644
--- a/source3/torture/locktest2.c
+++ b/source3/torture/locktest2.c
@@ -217,8 +217,15 @@ static struct cli_state *connect_one(char *share)
 
 	slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++);
 
-	nt_status = cli_full_connection_creds(&c, myname, server_n, NULL, 0, share, "?????",
-					      creds, 0, SMB_SIGNING_DEFAULT);
+	nt_status = cli_full_connection_creds(&c,
+					      myname,
+					      server_n,
+					      NULL,
+					      0,
+					      share,
+					      "?????",
+					      creds,
+					      0);
 	TALLOC_FREE(creds);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0, ("cli_full_connection failed with error %s\n", nt_errstr(nt_status)));
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 2a3133373e9..a4edeefd628 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -345,8 +345,7 @@ static bool torture_open_connection_share(struct cli_state **c,
 					   sharename,
 					   "?????",
 					   torture_creds,
-					   flags,
-					   signing_state);
+					   flags);
 	if (!NT_STATUS_IS_OK(status)) {
 		printf("failed to open share connection: //%s/%s port:%d - %s\n",
 			hostname, sharename, port_to_use, nt_errstr(status));
@@ -1523,8 +1522,7 @@ static bool run_tcon_devtype_test(int dummy)
 					   NULL, /* service */
 					   NULL, /* service_type */
 					   torture_creds,
-					   flags,
-					   signing_state);
+					   flags);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		printf("could not open connection\n");
diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c
index a3c879e75fb..2ac4fde7daf 100644
--- a/source3/utils/mdfind.c
+++ b/source3/utils/mdfind.c
@@ -153,8 +153,7 @@ int main(int argc, char **argv)
 					   "IPC$",
 					   "IPC",
 					   creds,
-					   flags,
-					   SMB_SIGNING_IPC_DEFAULT);
+					   flags);
 	if (!NT_STATUS_IS_OK(status)) {
 		DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status));
 		goto fail;
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 28ef6dc9974..7f5b9c3a440 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -2438,8 +2438,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
 					&server_ss, 0,
 					"IPC$", "IPC",
 					creds,
-					CLI_FULL_CONNECTION_IPC,
-					SMB_SIGNING_IPC_DEFAULT);
+					CLI_FULL_CONNECTION_IPC);
 
 	if (NT_STATUS_IS_ERR(nt_status)) {
 		d_fprintf(stderr, _("Unable to open a connection to %s to "
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index d01b2d8c771..b139fb2d0da 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -108,7 +108,6 @@ NTSTATUS connect_to_service(struct net_context *c,
 			    const char *service_type)
 {
 	NTSTATUS nt_status;
-	enum smb_signing_setting signing_setting = SMB_SIGNING_DEFAULT;
 	struct cli_credentials *creds = NULL;
 	int flags = 0;
 
@@ -119,7 +118,6 @@ NTSTATUS connect_to_service(struct net_context *c,
 	}
 
 	if (strequal(service_type, "IPC")) {
-		signing_setting = SMB_SIGNING_IPC_DEFAULT;
 		flags |= CLI_FULL_CONNECTION_IPC;
 	}
 
@@ -127,8 +125,7 @@ NTSTATUS connect_to_service(struct net_context *c,
 					server_ss, c->opt_port,
 					service_name, service_type,
 					creds,
-					flags,
-					signing_setting);
+					flags);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		d_fprintf(stderr, _("Could not connect to server %s\n"),
 			  server_name);
@@ -199,8 +196,7 @@ NTSTATUS connect_to_ipc_anonymous(struct net_context *c,
 					server_name, server_ss, c->opt_port,
 					"IPC$", "IPC",
 					anon_creds,
-					CLI_FULL_CONNECTION_IPC,
-					SMB_SIGNING_OFF);
+					CLI_FULL_CONNECTION_IPC);
 
 	if (NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
diff --git a/source3/utils/netlookup.c b/source3/utils/netlookup.c
index 2241beb331f..aaf78b0977a 100644
--- a/source3/utils/netlookup.c
+++ b/source3/utils/netlookup.c
@@ -99,8 +99,7 @@ static struct con_struct *create_cs(struct net_context *c,
 					&loopback_ss, 0,
 					"IPC$", "IPC",
 					anon_creds,
-					CLI_FULL_CONNECTION_IPC,
-					SMB_SIGNING_OFF);
+					CLI_FULL_CONNECTION_IPC);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status)));
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index f3209c31877..5983ebbd0a5 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -778,8 +778,7 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info,
 				NULL, 0,
 				share, "?????",
 				get_cmdline_auth_info_creds(auth_info),
-				flags,
-				get_cmdline_auth_info_signing_state(auth_info));
+				flags);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
 		return NULL;
diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c
index 954d6eba804..fea066ce468 100644
--- a/source3/utils/smbcquotas.c
+++ b/source3/utils/smbcquotas.c
@@ -527,9 +527,7 @@ static struct cli_state *connect_one(const char *share)
 					    share, "?????",
 					    get_cmdline_auth_info_creds(
 						popt_get_cmdline_auth_info()),
-					    flags,
-					    get_cmdline_auth_info_signing_state(
-						popt_get_cmdline_auth_info()));
+					    flags);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)));
 		return NULL;
-- 
2.29.2


From 49430d65ac0e11cdfec07c55b72f030c959f576f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Mon, 8 Jun 2020 08:04:24 +0200
Subject: [PATCH 033/104] s3:libsmb: Add encryption support to
 cli_full_connection_creds*()

Pair-Programmed-With: Andreas Schneider <asn@samba.org>

Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
---
 source3/libsmb/cliconnect.c | 166 ++++++++++++++++++++++++++++++++++++
 1 file changed, 166 insertions(+)

diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index b24743d789b..abfd18bfaf1 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -3352,6 +3352,10 @@ static int cli_full_connection_creds_state_destructor(
 static void cli_full_connection_creds_conn_done(struct tevent_req *subreq);
 static void cli_full_connection_creds_sess_start(struct tevent_req *req);
 static void cli_full_connection_creds_sess_done(struct tevent_req *subreq);
+static void cli_full_connection_creds_enc_start(struct tevent_req *req);
+static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq);
+static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq);
+static void cli_full_connection_creds_enc_done(struct tevent_req *subreq);
 static void cli_full_connection_creds_tcon_start(struct tevent_req *req);
 static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq);
 
@@ -3366,6 +3370,8 @@ struct tevent_req *cli_full_connection_creds_send(
 	struct tevent_req *req, *subreq;
 	struct cli_full_connection_creds_state *state;
 	enum smb_signing_setting signing_state;
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(creds);
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct cli_full_connection_creds_state);
@@ -3386,6 +3392,16 @@ struct tevent_req *cli_full_connection_creds_send(
 		signing_state = cli_credentials_get_smb_signing(creds);
 	}
 
+	if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
+		if (flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) {
+			encryption_state = SMB_ENCRYPTION_DESIRED;
+		}
+	}
+
+	if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
+		signing_state = SMB_SIGNING_REQUIRED;
+	}
+
 	subreq = cli_start_connection_send(
 		state, ev, my_name, dest_host, dest_ss, port,
 		signing_state, flags);
@@ -3460,6 +3476,156 @@ static void cli_full_connection_creds_sess_done(struct tevent_req *subreq)
 		return;
 	}
 
+	cli_full_connection_creds_enc_start(req);
+}
+
+static void cli_full_connection_creds_enc_start(struct tevent_req *req)
+{
+	struct cli_full_connection_creds_state *state = tevent_req_data(
+		req, struct cli_full_connection_creds_state);
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(state->creds);
+	struct tevent_req *subreq = NULL;
+	NTSTATUS status;
+
+	if (encryption_state < SMB_ENCRYPTION_DESIRED) {
+		cli_full_connection_creds_tcon_start(req);
+		return;
+	}
+
+	if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) {
+		status = smb2cli_session_encryption_on(state->cli->smb2.session);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+			if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
+				cli_full_connection_creds_tcon_start(req);
+				return;
+			}
+			d_printf("Encryption required and "
+				"server doesn't support "
+				"SMB3 encryption - failing connect\n");
+			tevent_req_nterror(req, status);
+			return;
+		} else if (!NT_STATUS_IS_OK(status)) {
+			d_printf("Encryption required and "
+				"setup failed with error %s.\n",
+				nt_errstr(status));
+			tevent_req_nterror(req, status);
+			return;
+		}
+
+		cli_full_connection_creds_tcon_start(req);
+		return;
+	}
+
+	if (!SERVER_HAS_UNIX_CIFS(state->cli)) {
+		if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
+			cli_full_connection_creds_tcon_start(req);
+			return;
+		}
+
+		status = NT_STATUS_NOT_SUPPORTED;
+		d_printf("Encryption required and "
+			"server doesn't support "
+			"SMB1 Unix Extensions - failing connect\n");
+		tevent_req_nterror(req, status);
+		return;
+	}
+
+	/*
+	 * We do a tcon on IPC$ just to setup the encryption,
+	 * the real tcon will be encrypted then.
+	 */
+	subreq = cli_tree_connect_send(state, state->ev, state->cli,
+				       "IPC$", "IPC", NULL);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, cli_full_connection_creds_enc_tcon, req);
+}
+
+static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_full_connection_creds_state *state = tevent_req_data(
+		req, struct cli_full_connection_creds_state);
+	NTSTATUS status;
+
+	status = cli_tree_connect_recv(subreq);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
+	subreq = cli_unix_extensions_version_send(state, state->ev, state->cli);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq, cli_full_connection_creds_enc_ver, req);
+}
+
+static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct cli_full_connection_creds_state *state = tevent_req_data(
+		req, struct cli_full_connection_creds_state);
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(state->creds);
+	uint16_t major, minor;
+	uint32_t caplow, caphigh;
+	NTSTATUS status;
+
+	status = cli_unix_extensions_version_recv(subreq,
+						  &major, &minor,
+						  &caplow,
+						  &caphigh);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
+			cli_full_connection_creds_tcon_start(req);
+			return;
+		}
+		DEBUG(10, ("%s: cli_unix_extensions_version "
+			   "returned %s\n", __func__, nt_errstr(status)));
+		tevent_req_nterror(req, NT_STATUS_UNKNOWN_REVISION);
+		return;
+	}
+
+	if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
+		if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
+			cli_full_connection_creds_tcon_start(req);
+			return;
+		}
+		DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP "
+			   "not supported\n", __func__));
+		tevent_req_nterror(req, NT_STATUS_UNSUPPORTED_COMPRESSION);
+		return;
+	}
+
+	subreq = cli_smb1_setup_encryption_send(state, state->ev,
+						state->cli,
+						state->creds);
+	if (tevent_req_nomem(subreq, req)) {
+		return;
+	}
+	tevent_req_set_callback(subreq,
+				cli_full_connection_creds_enc_done,
+				req);
+}
+
+static void cli_full_connection_creds_enc_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	NTSTATUS status;
+
+	status = cli_smb1_setup_encryption_recv(subreq);
+	TALLOC_FREE(subreq);
+	if (tevent_req_nterror(req, status)) {
+		return;
+	}
+
 	cli_full_connection_creds_tcon_start(req);
 }
 
-- 
2.29.2


From cc6eca3fe233c16d879f9a76aae022320e7044d7 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 11:26:00 +0200
Subject: [PATCH 034/104] python: Add a test for SMB encryption

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 python/samba/tests/libsmb.py | 37 ++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/python/samba/tests/libsmb.py b/python/samba/tests/libsmb.py
index e8f8e7fe94d..81d4e482644 100644
--- a/python/samba/tests/libsmb.py
+++ b/python/samba/tests/libsmb.py
@@ -21,10 +21,12 @@ from samba.samba3 import libsmb_samba_internal as libsmb
 from samba.dcerpc import security
 from samba.samba3 import param as s3param
 from samba import credentials
+from samba.credentials import SMB_ENCRYPTION_REQUIRED
 import samba.tests
 import threading
 import sys
 import os
+import random
 
 
 class LibsmbTestCase(samba.tests.TestCase):
@@ -77,6 +79,41 @@ class LibsmbTestCase(samba.tests.TestCase):
             if t.exc:
                 raise t.exc[0](t.exc[1])
 
+    def test_SMB3EncryptionRequired(self):
+        test_dir = 'testing_%d' % random.randint(0, 0xFFFF)
+
+        lp = s3param.get_context()
+        lp.load(os.getenv("SMB_CONF_PATH"))
+
+        creds = credentials.Credentials()
+        creds.guess(lp)
+        creds.set_username(os.getenv("USERNAME"))
+        creds.set_password(os.getenv("PASSWORD"))
+        creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+
+        c = libsmb.Conn(os.getenv("SERVER_IP"), "tmp",
+                        lp, creds)
+
+        c.mkdir(test_dir)
+        c.rmdir(test_dir)
+
+    def test_SMB1EncryptionRequired(self):
+        test_dir = 'testing_%d' % random.randint(0, 0xFFFF)
+
+        lp = s3param.get_context()
+        lp.load(os.getenv("SMB_CONF_PATH"))
+
+        creds = credentials.Credentials()
+        creds.guess(lp)
+        creds.set_username(os.getenv("USERNAME"))
+        creds.set_password(os.getenv("PASSWORD"))
+        creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+
+        c = libsmb.Conn(os.getenv("SERVER_IP"), "tmp",
+                        lp, creds, force_smb1=True)
+
+        c.mkdir(test_dir)
+        c.rmdir(test_dir)
 
 if __name__ == "__main__":
     import unittest
-- 
2.29.2


From 3bb0f6be56244767f78e8d0e085f2f7555585225 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:31:02 +0200
Subject: [PATCH 035/104] s3:net: Use cli_credentials_set_smb_encryption()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/utils/net_util.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index b139fb2d0da..5829d891075 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -148,16 +148,6 @@ NTSTATUS connect_to_service(struct net_context *c,
 		return nt_status;
 	}
 
-	if (c->smb_encrypt) {
-		nt_status = cli_cm_force_encryption_creds(*cli_ctx,
-							  creds,
-							  service_name);
-		if (!NT_STATUS_IS_OK(nt_status)) {
-			cli_shutdown(*cli_ctx);
-			*cli_ctx = NULL;
-		}
-	}
-
 	return nt_status;
 }
 
@@ -577,6 +567,12 @@ struct cli_credentials *net_context_creds(struct net_context *c,
 					     CRED_SPECIFIED);
 	}
 
+	if (c->smb_encrypt) {
+		cli_credentials_set_smb_encryption(creds,
+						   SMB_ENCRYPTION_REQUIRED,
+						   CRED_SPECIFIED);
+	}
+
 	return creds;
 }
 
-- 
2.29.2


From 16aaa2f7395d235f72582a5190c9bf5d90578b9d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:40:13 +0200
Subject: [PATCH 036/104] s3:libsmb: Use cli_credentials_set_smb_encryption()

This also adds a SMBC_ENCRYPTLEVEL_DEFAULT to 'enum
smbc_smb_encrypt_level' in order to use the smb.conf default value.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/include/libsmbclient.h          |   1 +
 source3/libsmb/ABI/smbclient-0.7.0.sigs | 188 ++++++++++++++++++++++++
 source3/libsmb/libsmb_context.c         |   4 +-
 source3/libsmb/libsmb_server.c          |  72 +++------
 source3/libsmb/wscript                  |   2 +-
 5 files changed, 216 insertions(+), 51 deletions(-)
 create mode 100644 source3/libsmb/ABI/smbclient-0.7.0.sigs

diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index c47e7c2a872..84c98089251 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -225,6 +225,7 @@ typedef enum smbc_share_mode
  */
 typedef enum smbc_smb_encrypt_level
 {
+    SMBC_ENCRYPTLEVEL_DEFAULT   = -1,
     SMBC_ENCRYPTLEVEL_NONE      = 0,
     SMBC_ENCRYPTLEVEL_REQUEST   = 1,
     SMBC_ENCRYPTLEVEL_REQUIRE   = 2
diff --git a/source3/libsmb/ABI/smbclient-0.7.0.sigs b/source3/libsmb/ABI/smbclient-0.7.0.sigs
new file mode 100644
index 00000000000..ee758e21b50
--- /dev/null
+++ b/source3/libsmb/ABI/smbclient-0.7.0.sigs
@@ -0,0 +1,188 @@
+smbc_chmod: int (const char *, mode_t)
+smbc_close: int (int)
+smbc_closedir: int (int)
+smbc_creat: int (const char *, mode_t)
+smbc_fgetxattr: int (int, const char *, const void *, size_t)
+smbc_flistxattr: int (int, char *, size_t)
+smbc_free_context: int (SMBCCTX *, int)
+smbc_fremovexattr: int (int, const char *)
+smbc_fsetxattr: int (int, const char *, const void *, size_t, int)
+smbc_fstat: int (int, struct stat *)
+smbc_fstatvfs: int (int, struct statvfs *)
+smbc_ftruncate: int (int, off_t)
+smbc_getDebug: int (SMBCCTX *)
+smbc_getFunctionAddCachedServer: smbc_add_cached_srv_fn (SMBCCTX *)
+smbc_getFunctionAuthData: smbc_get_auth_data_fn (SMBCCTX *)
+smbc_getFunctionAuthDataWithContext: smbc_get_auth_data_with_context_fn (SMBCCTX *)
+smbc_getFunctionCheckServer: smbc_check_server_fn (SMBCCTX *)
+smbc_getFunctionChmod: smbc_chmod_fn (SMBCCTX *)
+smbc_getFunctionClose: smbc_close_fn (SMBCCTX *)
+smbc_getFunctionClosedir: smbc_closedir_fn (SMBCCTX *)
+smbc_getFunctionCreat: smbc_creat_fn (SMBCCTX *)
+smbc_getFunctionFstat: smbc_fstat_fn (SMBCCTX *)
+smbc_getFunctionFstatVFS: smbc_fstatvfs_fn (SMBCCTX *)
+smbc_getFunctionFstatdir: smbc_fstatdir_fn (SMBCCTX *)
+smbc_getFunctionFtruncate: smbc_ftruncate_fn (SMBCCTX *)
+smbc_getFunctionGetCachedServer: smbc_get_cached_srv_fn (SMBCCTX *)
+smbc_getFunctionGetdents: smbc_getdents_fn (SMBCCTX *)
+smbc_getFunctionGetxattr: smbc_getxattr_fn (SMBCCTX *)
+smbc_getFunctionListPrintJobs: smbc_list_print_jobs_fn (SMBCCTX *)
+smbc_getFunctionListxattr: smbc_listxattr_fn (SMBCCTX *)
+smbc_getFunctionLseek: smbc_lseek_fn (SMBCCTX *)
+smbc_getFunctionLseekdir: smbc_lseekdir_fn (SMBCCTX *)
+smbc_getFunctionMkdir: smbc_mkdir_fn (SMBCCTX *)
+smbc_getFunctionNotify: smbc_notify_fn (SMBCCTX *)
+smbc_getFunctionOpen: smbc_open_fn (SMBCCTX *)
+smbc_getFunctionOpenPrintJob: smbc_open_print_job_fn (SMBCCTX *)
+smbc_getFunctionOpendir: smbc_opendir_fn (SMBCCTX *)
+smbc_getFunctionPrintFile: smbc_print_file_fn (SMBCCTX *)
+smbc_getFunctionPurgeCachedServers: smbc_purge_cached_fn (SMBCCTX *)
+smbc_getFunctionRead: smbc_read_fn (SMBCCTX *)
+smbc_getFunctionReaddir: smbc_readdir_fn (SMBCCTX *)
+smbc_getFunctionReaddirPlus: smbc_readdirplus_fn (SMBCCTX *)
+smbc_getFunctionReaddirPlus2: smbc_readdirplus2_fn (SMBCCTX *)
+smbc_getFunctionRemoveCachedServer: smbc_remove_cached_srv_fn (SMBCCTX *)
+smbc_getFunctionRemoveUnusedServer: smbc_remove_unused_server_fn (SMBCCTX *)
+smbc_getFunctionRemovexattr: smbc_removexattr_fn (SMBCCTX *)
+smbc_getFunctionRename: smbc_rename_fn (SMBCCTX *)
+smbc_getFunctionRmdir: smbc_rmdir_fn (SMBCCTX *)
+smbc_getFunctionSetxattr: smbc_setxattr_fn (SMBCCTX *)
+smbc_getFunctionSplice: smbc_splice_fn (SMBCCTX *)
+smbc_getFunctionStat: smbc_stat_fn (SMBCCTX *)
+smbc_getFunctionStatVFS: smbc_statvfs_fn (SMBCCTX *)
+smbc_getFunctionTelldir: smbc_telldir_fn (SMBCCTX *)
+smbc_getFunctionUnlink: smbc_unlink_fn (SMBCCTX *)
+smbc_getFunctionUnlinkPrintJob: smbc_unlink_print_job_fn (SMBCCTX *)
+smbc_getFunctionUtimes: smbc_utimes_fn (SMBCCTX *)
+smbc_getFunctionWrite: smbc_write_fn (SMBCCTX *)
+smbc_getNetbiosName: const char *(SMBCCTX *)
+smbc_getOptionBrowseMaxLmbCount: int (SMBCCTX *)
+smbc_getOptionCaseSensitive: smbc_bool (SMBCCTX *)
+smbc_getOptionDebugToStderr: smbc_bool (SMBCCTX *)
+smbc_getOptionFallbackAfterKerberos: smbc_bool (SMBCCTX *)
+smbc_getOptionFullTimeNames: smbc_bool (SMBCCTX *)
+smbc_getOptionNoAutoAnonymousLogin: smbc_bool (SMBCCTX *)
+smbc_getOptionOneSharePerServer: smbc_bool (SMBCCTX *)
+smbc_getOptionOpenShareMode: smbc_share_mode (SMBCCTX *)
+smbc_getOptionSmbEncryptionLevel: smbc_smb_encrypt_level (SMBCCTX *)
+smbc_getOptionUrlEncodeReaddirEntries: smbc_bool (SMBCCTX *)
+smbc_getOptionUseCCache: smbc_bool (SMBCCTX *)
+smbc_getOptionUseKerberos: smbc_bool (SMBCCTX *)
+smbc_getOptionUseNTHash: smbc_bool (SMBCCTX *)
+smbc_getOptionUserData: void *(SMBCCTX *)
+smbc_getPort: uint16_t (SMBCCTX *)
+smbc_getServerCacheData: struct smbc_server_cache *(SMBCCTX *)
+smbc_getTimeout: int (SMBCCTX *)
+smbc_getUser: const char *(SMBCCTX *)
+smbc_getWorkgroup: const char *(SMBCCTX *)
+smbc_getdents: int (unsigned int, struct smbc_dirent *, int)
+smbc_getxattr: int (const char *, const char *, const void *, size_t)
+smbc_init: int (smbc_get_auth_data_fn, int)
+smbc_init_context: SMBCCTX *(SMBCCTX *)
+smbc_lgetxattr: int (const char *, const char *, const void *, size_t)
+smbc_list_print_jobs: int (const char *, smbc_list_print_job_fn)
+smbc_listxattr: int (const char *, char *, size_t)
+smbc_llistxattr: int (const char *, char *, size_t)
+smbc_lremovexattr: int (const char *, const char *)
+smbc_lseek: off_t (int, off_t, int)
+smbc_lseekdir: int (int, off_t)
+smbc_lsetxattr: int (const char *, const char *, const void *, size_t, int)
+smbc_mkdir: int (const char *, mode_t)
+smbc_new_context: SMBCCTX *(void)
+smbc_notify: int (int, smbc_bool, uint32_t, unsigned int, smbc_notify_callback_fn, void *)
+smbc_open: int (const char *, int, mode_t)
+smbc_open_print_job: int (const char *)
+smbc_opendir: int (const char *)
+smbc_option_get: void *(SMBCCTX *, char *)
+smbc_option_set: void (SMBCCTX *, char *, ...)
+smbc_print_file: int (const char *, const char *)
+smbc_read: ssize_t (int, void *, size_t)
+smbc_readdir: struct smbc_dirent *(unsigned int)
+smbc_readdirplus: const struct libsmb_file_info *(unsigned int)
+smbc_readdirplus2: const struct libsmb_file_info *(unsigned int, struct stat *)
+smbc_removexattr: int (const char *, const char *)
+smbc_rename: int (const char *, const char *)
+smbc_rmdir: int (const char *)
+smbc_setConfiguration: int (SMBCCTX *, const char *)
+smbc_setDebug: void (SMBCCTX *, int)
+smbc_setFunctionAddCachedServer: void (SMBCCTX *, smbc_add_cached_srv_fn)
+smbc_setFunctionAuthData: void (SMBCCTX *, smbc_get_auth_data_fn)
+smbc_setFunctionAuthDataWithContext: void (SMBCCTX *, smbc_get_auth_data_with_context_fn)
+smbc_setFunctionCheckServer: void (SMBCCTX *, smbc_check_server_fn)
+smbc_setFunctionChmod: void (SMBCCTX *, smbc_chmod_fn)
+smbc_setFunctionClose: void (SMBCCTX *, smbc_close_fn)
+smbc_setFunctionClosedir: void (SMBCCTX *, smbc_closedir_fn)
+smbc_setFunctionCreat: void (SMBCCTX *, smbc_creat_fn)
+smbc_setFunctionFstat: void (SMBCCTX *, smbc_fstat_fn)
+smbc_setFunctionFstatVFS: void (SMBCCTX *, smbc_fstatvfs_fn)
+smbc_setFunctionFstatdir: void (SMBCCTX *, smbc_fstatdir_fn)
+smbc_setFunctionFtruncate: void (SMBCCTX *, smbc_ftruncate_fn)
+smbc_setFunctionGetCachedServer: void (SMBCCTX *, smbc_get_cached_srv_fn)
+smbc_setFunctionGetdents: void (SMBCCTX *, smbc_getdents_fn)
+smbc_setFunctionGetxattr: void (SMBCCTX *, smbc_getxattr_fn)
+smbc_setFunctionListPrintJobs: void (SMBCCTX *, smbc_list_print_jobs_fn)
+smbc_setFunctionListxattr: void (SMBCCTX *, smbc_listxattr_fn)
+smbc_setFunctionLseek: void (SMBCCTX *, smbc_lseek_fn)
+smbc_setFunctionLseekdir: void (SMBCCTX *, smbc_lseekdir_fn)
+smbc_setFunctionMkdir: void (SMBCCTX *, smbc_mkdir_fn)
+smbc_setFunctionNotify: void (SMBCCTX *, smbc_notify_fn)
+smbc_setFunctionOpen: void (SMBCCTX *, smbc_open_fn)
+smbc_setFunctionOpenPrintJob: void (SMBCCTX *, smbc_open_print_job_fn)
+smbc_setFunctionOpendir: void (SMBCCTX *, smbc_opendir_fn)
+smbc_setFunctionPrintFile: void (SMBCCTX *, smbc_print_file_fn)
+smbc_setFunctionPurgeCachedServers: void (SMBCCTX *, smbc_purge_cached_fn)
+smbc_setFunctionRead: void (SMBCCTX *, smbc_read_fn)
+smbc_setFunctionReaddir: void (SMBCCTX *, smbc_readdir_fn)
+smbc_setFunctionReaddirPlus: void (SMBCCTX *, smbc_readdirplus_fn)
+smbc_setFunctionReaddirPlus2: void (SMBCCTX *, smbc_readdirplus2_fn)
+smbc_setFunctionRemoveCachedServer: void (SMBCCTX *, smbc_remove_cached_srv_fn)
+smbc_setFunctionRemoveUnusedServer: void (SMBCCTX *, smbc_remove_unused_server_fn)
+smbc_setFunctionRemovexattr: void (SMBCCTX *, smbc_removexattr_fn)
+smbc_setFunctionRename: void (SMBCCTX *, smbc_rename_fn)
+smbc_setFunctionRmdir: void (SMBCCTX *, smbc_rmdir_fn)
+smbc_setFunctionSetxattr: void (SMBCCTX *, smbc_setxattr_fn)
+smbc_setFunctionSplice: void (SMBCCTX *, smbc_splice_fn)
+smbc_setFunctionStat: void (SMBCCTX *, smbc_stat_fn)
+smbc_setFunctionStatVFS: void (SMBCCTX *, smbc_statvfs_fn)
+smbc_setFunctionTelldir: void (SMBCCTX *, smbc_telldir_fn)
+smbc_setFunctionUnlink: void (SMBCCTX *, smbc_unlink_fn)
+smbc_setFunctionUnlinkPrintJob: void (SMBCCTX *, smbc_unlink_print_job_fn)
+smbc_setFunctionUtimes: void (SMBCCTX *, smbc_utimes_fn)
+smbc_setFunctionWrite: void (SMBCCTX *, smbc_write_fn)
+smbc_setLogCallback: void (SMBCCTX *, void *, smbc_debug_callback_fn)
+smbc_setNetbiosName: void (SMBCCTX *, const char *)
+smbc_setOptionBrowseMaxLmbCount: void (SMBCCTX *, int)
+smbc_setOptionCaseSensitive: void (SMBCCTX *, smbc_bool)
+smbc_setOptionDebugToStderr: void (SMBCCTX *, smbc_bool)
+smbc_setOptionFallbackAfterKerberos: void (SMBCCTX *, smbc_bool)
+smbc_setOptionFullTimeNames: void (SMBCCTX *, smbc_bool)
+smbc_setOptionNoAutoAnonymousLogin: void (SMBCCTX *, smbc_bool)
+smbc_setOptionOneSharePerServer: void (SMBCCTX *, smbc_bool)
+smbc_setOptionOpenShareMode: void (SMBCCTX *, smbc_share_mode)
+smbc_setOptionProtocols: smbc_bool (SMBCCTX *, const char *, const char *)
+smbc_setOptionSmbEncryptionLevel: void (SMBCCTX *, smbc_smb_encrypt_level)
+smbc_setOptionUrlEncodeReaddirEntries: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUseCCache: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUseKerberos: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUseNTHash: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUserData: void (SMBCCTX *, void *)
+smbc_setPort: void (SMBCCTX *, uint16_t)
+smbc_setServerCacheData: void (SMBCCTX *, struct smbc_server_cache *)
+smbc_setTimeout: void (SMBCCTX *, int)
+smbc_setUser: void (SMBCCTX *, const char *)
+smbc_setWorkgroup: void (SMBCCTX *, const char *)
+smbc_set_context: SMBCCTX *(SMBCCTX *)
+smbc_set_credentials: void (const char *, const char *, const char *, smbc_bool, const char *)
+smbc_set_credentials_with_fallback: void (SMBCCTX *, const char *, const char *, const char *)
+smbc_setxattr: int (const char *, const char *, const void *, size_t, int)
+smbc_stat: int (const char *, struct stat *)
+smbc_statvfs: int (char *, struct statvfs *)
+smbc_telldir: off_t (int)
+smbc_unlink: int (const char *)
+smbc_unlink_print_job: int (const char *, int)
+smbc_urldecode: int (char *, char *, size_t)
+smbc_urlencode: int (char *, char *, int)
+smbc_utime: int (const char *, struct utimbuf *)
+smbc_utimes: int (const char *, struct timeval *)
+smbc_version: const char *(void)
+smbc_write: ssize_t (int, const void *, size_t)
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index eaa0cdeca93..ea741f41c7d 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -171,7 +171,7 @@ smbc_new_context(void)
 
         smbc_setOptionFullTimeNames(context, False);
         smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE);
-        smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE);
+        smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_DEFAULT);
         smbc_setOptionUseCCache(context, True);
         smbc_setOptionCaseSensitive(context, False);
         smbc_setOptionBrowseMaxLmbCount(context, 3);    /* # LMBs to query */
@@ -474,6 +474,8 @@ smbc_option_get(SMBCCTX *context,
         } else if (strcmp(option_name, "smb_encrypt_level") == 0) {
                 switch(smbc_getOptionSmbEncryptionLevel(context))
                 {
+                case SMBC_ENCRYPTLEVEL_DEFAULT:
+                        return discard_const_p(void, "default");
                 case 0:
                         return discard_const_p(void, "none");
                 case 1:
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index 33dc8419deb..eb58d7c6ac9 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -284,6 +284,29 @@ static struct cli_credentials *SMBC_auth_credentials(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+	switch (context->internal->smb_encryption_level) {
+	case SMBC_ENCRYPTLEVEL_DEFAULT:
+		/* Use the config option */
+		break;
+	case SMBC_ENCRYPTLEVEL_NONE:
+		cli_credentials_set_smb_encryption(creds,
+						   SMB_ENCRYPTION_OFF,
+						   CRED_SPECIFIED);
+		break;
+	case SMBC_ENCRYPTLEVEL_REQUEST:
+		cli_credentials_set_smb_encryption(creds,
+						   SMB_ENCRYPTION_DESIRED,
+						   CRED_SPECIFIED);
+		break;
+	case SMBC_ENCRYPTLEVEL_REQUIRE:
+	default:
+		cli_credentials_set_smb_encryption(creds,
+						   SMB_ENCRYPTION_REQUIRED,
+						   CRED_SPECIFIED);
+		break;
+	}
+
+
 	return creds;
 }
 
@@ -625,30 +648,6 @@ SMBC_server_internal(TALLOC_CTX *ctx,
 		smbXcli_tcon_set_fs_attributes(tcon, fs_attrs);
         }
 
-	if (context->internal->smb_encryption_level) {
-		/* Attempt encryption. */
-		status = cli_cm_force_encryption_creds(c,
-						       creds,
-						       share);
-		if (!NT_STATUS_IS_OK(status)) {
-
-			/*
-			 * context->smb_encryption_level == 1
-			 * means don't fail if encryption can't be negotiated,
-			 * == 2 means fail if encryption can't be negotiated.
-			 */
-
-			DEBUG(4,(" SMB encrypt failed\n"));
-
-			if (context->internal->smb_encryption_level == 2) {
-	                        cli_shutdown(c);
-				errno = EPERM;
-				return NULL;
-			}
-		}
-		DEBUG(4,(" SMB encrypt ok\n"));
-	}
-
 	/*
 	 * Ok, we have got a nice connection
 	 * Let's allocate a server structure.
@@ -825,31 +824,6 @@ SMBC_attr_server(TALLOC_CTX *ctx,
                 }
 		talloc_steal(ipc_cli, creds);
 
-		if (context->internal->smb_encryption_level) {
-			/* Attempt encryption. */
-			nt_status = cli_cm_force_encryption_creds(ipc_cli,
-								  creds,
-								  "IPC$");
-			if (!NT_STATUS_IS_OK(nt_status)) {
-
-				/*
-				 * context->smb_encryption_level ==
-				 * 1 means don't fail if encryption can't be
-				 * negotiated, == 2 means fail if encryption
-				 * can't be negotiated.
-				 */
-
-				DEBUG(4,(" SMB encrypt failed on IPC$\n"));
-
-				if (context->internal->smb_encryption_level == 2) {
-		                        cli_shutdown(ipc_cli);
-					errno = EPERM;
-					return NULL;
-				}
-			}
-			DEBUG(4,(" SMB encrypt ok on IPC$\n"));
-		}
-
                 ipc_srv = SMB_MALLOC_P(SMBCSRV);
                 if (!ipc_srv) {
                         errno = ENOMEM;
diff --git a/source3/libsmb/wscript b/source3/libsmb/wscript
index ec4a516b2ee..61503d0a98b 100644
--- a/source3/libsmb/wscript
+++ b/source3/libsmb/wscript
@@ -26,5 +26,5 @@ def build(bld):
                        public_headers='../include/libsmbclient.h',
                        abi_directory='ABI',
                        abi_match='smbc_*',
-                       vnum='0.6.0',
+                       vnum='0.7.0',
                        pc_files='smbclient.pc')
-- 
2.29.2


From eaa0bdc5931b82f9adbb65070252208be26a9d28 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:43:33 +0200
Subject: [PATCH 037/104] s3:client: Remove unused smb encryption code

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/client/smbspool.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index f56dc323b6e..16a8d44c069 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -584,16 +584,6 @@ smb_complete_connection(struct cli_state **output_cli,
 
 		return nt_status;
 	}
-#if 0
-	/* Need to work out how to specify this on the URL. */
-	if (smb_encrypt) {
-		if (!cli_cm_force_encryption_creds(cli, creds, share)) {
-			fprintf(stderr, "ERROR: encryption setup failed\n");
-			cli_shutdown(cli);
-			return NULL;
-		}
-	}
-#endif
 
 	*output_cli = cli;
 	return NT_STATUS_OK;
-- 
2.29.2


From 63179da4a51fefc5d938339360d579f725875389 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:47:05 +0200
Subject: [PATCH 038/104] s3:utils: Remove obsolete force encryption from
 smbacls

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/utils/smbcacls.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 5983ebbd0a5..8fd9fcc5780 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -784,16 +784,6 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info,
 		return NULL;
 	}
 
-	if (get_cmdline_auth_info_smb_encrypt(auth_info)) {
-		nt_status = cli_cm_force_encryption_creds(c,
-					get_cmdline_auth_info_creds(auth_info),
-					share);
-                if (!NT_STATUS_IS_OK(nt_status)) {
-			cli_shutdown(c);
-			c = NULL;
-                }
-	}
-
 	return c;
 }
 
-- 
2.29.2


From f113666b62c0fbe960f9ac22aea63241b56ffc61 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:48:18 +0200
Subject: [PATCH 039/104] s3:utils: Remove obsolete force encryption from
 mdfind

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/utils/mdfind.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c
index 2ac4fde7daf..ef2657e4fa5 100644
--- a/source3/utils/mdfind.c
+++ b/source3/utils/mdfind.c
@@ -159,13 +159,6 @@ int main(int argc, char **argv)
 		goto fail;
 	}
 
-	if (get_cmdline_auth_info_smb_encrypt(auth)) {
-		status = cli_cm_force_encryption_creds(cli, creds, "IPC$");
-		if (!NT_STATUS_IS_OK(status)) {
-			goto fail;
-		}
-	}
-
 	status = cli_rpc_pipe_open_noauth_transport(cli,
 						    NCACN_NP,
 						    &ndr_table_mdssvc,
-- 
2.29.2


From 4f3770237e1a3d41c725560d9e5c14786b98d2f9 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:49:28 +0200
Subject: [PATCH 040/104] s3:utils: Remove obsolete force encryption from
 smbcquotas

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/utils/smbcquotas.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c
index fea066ce468..4ceac7b3ab0 100644
--- a/source3/utils/smbcquotas.c
+++ b/source3/utils/smbcquotas.c
@@ -533,17 +533,6 @@ static struct cli_state *connect_one(const char *share)
 		return NULL;
 	}
 
-	if (get_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info())) {
-		nt_status = cli_cm_force_encryption_creds(c,
-					get_cmdline_auth_info_creds(
-						popt_get_cmdline_auth_info()),
-					share);
-		if (!NT_STATUS_IS_OK(nt_status)) {
-			cli_shutdown(c);
-			return NULL;
-		}
-	}
-
 	return c;
 }
 
-- 
2.29.2


From b897f3360dae5737d646dbce9f7571b1cfb070b0 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 10 Jun 2020 12:51:18 +0200
Subject: [PATCH 041/104] s3:rpcclient: Remove obsolete force encryption from
 rpcclient

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/rpcclient/rpcclient.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 2ead6cc7ba5..575a42ebf70 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -1214,17 +1214,6 @@ out_free:
 		goto done;
 	}
 
-	if (get_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info())) {
-		nt_status = cli_cm_force_encryption_creds(cli,
-					get_cmdline_auth_info_creds(
-						popt_get_cmdline_auth_info()),
-					"IPC$");
-		if (!NT_STATUS_IS_OK(nt_status)) {
-			result = 1;
-			goto done;
-		}
-	}
-
 #if 0	/* COMMENT OUT FOR TESTING */
 	memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password));
 #endif
-- 
2.29.2


From b01458095b5e815c09eb71fb597598e9f34ee342 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 6 Jul 2020 10:58:36 +0200
Subject: [PATCH 042/104] examples: Remove obsolete force encryption from
 smb2mount

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 examples/fuse/smb2mount.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/examples/fuse/smb2mount.c b/examples/fuse/smb2mount.c
index 6206c3a9701..c64be573462 100644
--- a/examples/fuse/smb2mount.c
+++ b/examples/fuse/smb2mount.c
@@ -44,17 +44,6 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info,
 		return NULL;
 	}
 
-	if (get_cmdline_auth_info_smb_encrypt(auth_info)) {
-		nt_status = cli_cm_force_encryption_creds(
-			c,
-			get_cmdline_auth_info_creds(auth_info),
-			share);
-                if (!NT_STATUS_IS_OK(nt_status)) {
-			cli_shutdown(c);
-			c = NULL;
-                }
-	}
-
 	return c;
 }
 
-- 
2.29.2


From 66eb5d32234f2e7700a43504158507a6f828c50b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 6 Jul 2020 11:05:59 +0200
Subject: [PATCH 043/104] s3:libsmb: Make cli_cm_force_encryption_creds()
 static

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source3/libsmb/clidfs.c | 6 +++---
 source3/libsmb/proto.h  | 3 ---
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 4495a027830..aff998f6187 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -43,9 +43,9 @@
  Ensure a connection is encrypted.
 ********************************************************************/
 
-NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c,
-				       struct cli_credentials *creds,
-				       const char *sharename)
+static NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c,
+					      struct cli_credentials *creds,
+					      const char *sharename)
 {
 	uint16_t major, minor;
 	uint32_t caplow, caphigh;
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 850cf12c8a6..eeabcaa7463 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -123,9 +123,6 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
 
 /* The following definitions come from libsmb/clidfs.c  */
 
-NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c,
-				       struct cli_credentials *creds,
-				       const char *sharename);
 NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				struct cli_state *referring_cli,
 				const char *server,
-- 
2.29.2


From 3b8e9646f0a79e2cbb977b8c1d0fc5f28a9b7490 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 13 Aug 2020 16:16:55 +0200
Subject: [PATCH 044/104] s4:libcli: Return NTSTATUS errors for
 smb_composite_connect_send()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source4/libcli/smb_composite/connect.c | 40 +++++++++++++++++++-------
 1 file changed, 29 insertions(+), 11 deletions(-)

diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c
index 582d43ef173..ad50ae0ac81 100644
--- a/source4/libcli/smb_composite/connect.c
+++ b/source4/libcli/smb_composite/connect.c
@@ -420,15 +420,25 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec
 	struct connect_state *state;
 
 	c = talloc_zero(mem_ctx, struct composite_context);
-	if (c == NULL) goto failed;
-
-	c->event_ctx = event_ctx;
-	if (c->event_ctx == NULL) goto failed;
+	if (c == NULL) {
+		goto nomem;
+	}
 
 	state = talloc_zero(c, struct connect_state);
-	if (state == NULL) goto failed;
+	if (state == NULL) {
+		goto nomem;
+	}
+
+	c->event_ctx = event_ctx;
+	if (c->event_ctx == NULL) {
+		composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
+		return c;
+	}
 
-	if (io->in.gensec_settings == NULL) goto failed;
+	if (io->in.gensec_settings == NULL) {
+		composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX);
+		return c;
+	}
 	state->io = io;
 
 	c->state = COMPOSITE_STATE_IN_PROGRESS;
@@ -449,12 +459,14 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec
 						   &io->in.options,
 						   &state->transport);
 		if (!NT_STATUS_IS_OK(status)) {
-			goto failed;
+			composite_error(c, status);
+			return c;
 		}
 
 		status = connect_send_session(c, io);
 		if (!NT_STATUS_IS_OK(status)) {
-			goto failed;
+			composite_error(c, status);
+			return c;
 		}
 
 		return c;
@@ -468,15 +480,18 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec
 					       io->in.socket_options,
 					       &state->calling,
 					       &state->called);
-	if (state->creq == NULL) goto failed;
+	if (state->creq == NULL) {
+		composite_error(c, NT_STATUS_NO_MEMORY);
+		return c;
+	}
 
 	state->stage = CONNECT_SOCKET;
 	state->creq->async.private_data = c;
 	state->creq->async.fn = composite_handler;
 
 	return c;
-failed:
-	talloc_free(c);
+nomem:
+	TALLOC_FREE(c);
 	return NULL;
 }
 
@@ -506,5 +521,8 @@ NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem
 			       struct tevent_context *ev)
 {
 	struct composite_context *c = smb_composite_connect_send(io, mem_ctx, resolve_ctx, ev);
+	if (c == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
 	return smb_composite_connect_recv(c, mem_ctx);
 }
-- 
2.29.2


From cecd31a2451e20046c0202837269fb533e3118a7 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 7 Jul 2020 12:54:26 +0200
Subject: [PATCH 045/104] s4:libcli: Return if encryption is requested for SMB1

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source4/libcli/smb_composite/sesssetup.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c
index 6ee4929e8d7..51e121bdce6 100644
--- a/source4/libcli/smb_composite/sesssetup.c
+++ b/source4/libcli/smb_composite/sesssetup.c
@@ -620,10 +620,17 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se
 	struct composite_context *c;
 	struct sesssetup_state *state;
 	NTSTATUS status;
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(io->in.credentials);
 
 	c = composite_create(session, session->transport->ev);
 	if (c == NULL) return NULL;
 
+	if (encryption_state > SMB_ENCRYPTION_DESIRED) {
+		composite_error(c, NT_STATUS_PROTOCOL_NOT_SUPPORTED);
+		return c;
+	}
+
 	state = talloc_zero(c, struct sesssetup_state);
 	if (composite_nomem(state, c)) return c;
 	c->private_data = state;
-- 
2.29.2


From ed5b2f36fec30ae7b277620cb82f01a07f027e0e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 7 Jul 2020 12:29:39 +0200
Subject: [PATCH 046/104] s3:libcli: Split out smb2_connect_tcon_start()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source4/libcli/smb2/connect.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 6fc3993a4e8..95ff05eac8f 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -237,6 +237,7 @@ static void smb2_connect_session_start(struct tevent_req *req)
 	tevent_req_set_callback(subreq, smb2_connect_session_done, req);
 }
 
+static void smb2_connect_tcon_start(struct tevent_req *req);
 static void smb2_connect_tcon_done(struct tevent_req *subreq);
 
 static void smb2_connect_session_done(struct tevent_req *subreq)
@@ -248,7 +249,6 @@ static void smb2_connect_session_done(struct tevent_req *subreq)
 		tevent_req_data(req,
 		struct smb2_connect_state);
 	NTSTATUS status;
-	uint32_t timeout_msec;
 
 	status = smb2_session_setup_spnego_recv(subreq);
 	TALLOC_FREE(subreq);
@@ -289,6 +289,17 @@ static void smb2_connect_session_done(struct tevent_req *subreq)
 		return;
 	}
 
+	smb2_connect_tcon_start(req);
+}
+
+static void smb2_connect_tcon_start(struct tevent_req *req)
+{
+	struct smb2_connect_state *state =
+		tevent_req_data(req,
+				struct smb2_connect_state);
+	struct tevent_req *subreq = NULL;
+	uint32_t timeout_msec;
+
 	timeout_msec = state->transport->options.request_timeout * 1000;
 
 	subreq = smb2cli_tcon_send(state, state->ev,
-- 
2.29.2


From 7eb81b6448064d8beee3972471723b90ea9307ec Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 7 Jul 2020 12:44:26 +0200
Subject: [PATCH 047/104] s4:libcli: Add smb2_connect_enc_start()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source4/libcli/smb2/connect.c | 38 +++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 95ff05eac8f..3a3ecdf20e8 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -237,6 +237,7 @@ static void smb2_connect_session_start(struct tevent_req *req)
 	tevent_req_set_callback(subreq, smb2_connect_session_done, req);
 }
 
+static void smb2_connect_enc_start(struct tevent_req *req);
 static void smb2_connect_tcon_start(struct tevent_req *req);
 static void smb2_connect_tcon_done(struct tevent_req *subreq);
 
@@ -289,6 +290,43 @@ static void smb2_connect_session_done(struct tevent_req *subreq)
 		return;
 	}
 
+	smb2_connect_enc_start(req);
+}
+
+static void smb2_connect_enc_start(struct tevent_req *req)
+{
+	struct smb2_connect_state *state =
+		tevent_req_data(req,
+				struct smb2_connect_state);
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(state->credentials);
+	NTSTATUS status;
+
+	if (encryption_state < SMB_ENCRYPTION_DESIRED) {
+		smb2_connect_tcon_start(req);
+		return;
+	}
+
+	status = smb2cli_session_encryption_on(state->session->smbXcli);
+	if (!NT_STATUS_IS_OK(status)) {
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+			if (encryption_state < SMB_ENCRYPTION_REQUIRED) {
+				smb2_connect_tcon_start(req);
+				return;
+			}
+
+			DBG_ERR("Encryption required and server doesn't support "
+				"SMB3 encryption - failing connect\n");
+			tevent_req_nterror(req, status);
+			return;
+		}
+
+		DBG_ERR("Encryption required and setup failed with error %s.\n",
+			nt_errstr(status));
+		tevent_req_nterror(req, NT_STATUS_PROTOCOL_NOT_SUPPORTED);
+		return;
+	}
+
 	smb2_connect_tcon_start(req);
 }
 
-- 
2.29.2


From b5b0c28d597d8ef98b632e4616d2d2cdaaad37a9 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 24 Jul 2020 10:18:52 +0200
Subject: [PATCH 048/104] s4:libcli: Require signing for SMB encryption

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
---
 source4/libcli/smb2/connect.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 3a3ecdf20e8..9540704491e 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -31,6 +31,7 @@
 #include "param/param.h"
 #include "auth/credentials/credentials.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "smb2_constants.h"
 
 struct smb2_connect_state {
 	struct tevent_context *ev;
@@ -76,6 +77,8 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 	struct smb2_connect_state *state;
 	struct composite_context *creq;
 	static const char *default_ports[] = { "445", "139", NULL };
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(credentials);
 
 	req = tevent_req_create(mem_ctx, &state,
 				struct smb2_connect_state);
@@ -99,6 +102,10 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 		state->ports = default_ports;
 	}
 
+	if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
+		state->options.signing = SMB_SIGNING_REQUIRED;
+	}
+
 	make_nbt_name_client(&state->calling,
 			     cli_credentials_get_workstation(credentials));
 
@@ -116,7 +123,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
 
 		status = smb2_transport_raw_init(state, ev,
 						 existing_conn,
-						 options,
+						 &state->options,
 						 &state->transport);
 		if (tevent_req_nterror(req, status)) {
 			return tevent_req_post(req, ev);
-- 
2.29.2


From ee95e01cdc3917fc371b3145dcbe6d23ffc054b1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 7 Jul 2020 14:27:07 +0200
Subject: [PATCH 049/104] python:tests: Add test for SMB encrypted DCERPC
 connection

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Wed Aug 19 17:46:28 UTC 2020 on sn-devel-184
---
 python/samba/tests/dcerpc/binding.py | 82 ++++++++++++++++++++++++++++
 selftest/tests.py                    |  1 +
 2 files changed, 83 insertions(+)
 create mode 100644 python/samba/tests/dcerpc/binding.py

diff --git a/python/samba/tests/dcerpc/binding.py b/python/samba/tests/dcerpc/binding.py
new file mode 100644
index 00000000000..8e0d6a5ef0a
--- /dev/null
+++ b/python/samba/tests/dcerpc/binding.py
@@ -0,0 +1,82 @@
+#
+# Unix SMB/CIFS implementation.
+# Copyright (c) 2020      Andreas Schneider <asn@samba.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""Tests for samba.dcerpc., credentials and binding strings"""
+
+import samba.tests
+from samba.tests import RpcInterfaceTestCase, TestCase
+from samba.dcerpc import lsa
+import samba.dcerpc.security as security
+from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED
+from samba import NTSTATUSError
+
+class RpcBindingTests(RpcInterfaceTestCase):
+    def setUp(self):
+        super(RpcBindingTests, self).setUp()
+
+    def get_user_creds(self):
+        c = Credentials()
+        c.guess()
+        domain = samba.tests.env_get_var_value('DOMAIN')
+        username = samba.tests.env_get_var_value('USERNAME')
+        password = samba.tests.env_get_var_value('PASSWORD')
+        c.set_domain(domain)
+        c.set_username(username)
+        c.set_password(password)
+        return c
+
+    def test_smb3_dcerpc_encryption(self):
+        creds = self.get_user_creds()
+        creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+
+        lp = self.get_loadparm()
+        lp.set('client ipc max protocol', 'SMB3')
+        lp.set('client ipc min protocol', 'SMB3')
+
+        binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')))
+        lsa_conn = lsa.lsarpc(binding_string, lp, creds)
+
+        objectAttr = lsa.ObjectAttribute()
+        objectAttr.sec_qos = lsa.QosInfo()
+
+        pol_handle = lsa_conn.OpenPolicy2('',
+                                          objectAttr,
+                                          security.SEC_FLAG_MAXIMUM_ALLOWED)
+        self.assertIsNotNone(pol_handle)
+
+    def test_smb2_dcerpc_encryption(self):
+        creds = self.get_user_creds()
+        creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+
+        lp = self.get_loadparm()
+        lp.set('client ipc max protocol', 'SMB2')
+        lp.set('client ipc min protocol', 'SMB2')
+
+        binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')))
+        self.assertRaises(NTSTATUSError, lsa.lsarpc, binding_string, lp, creds)
+
+    def test_smb1_dcerpc_encryption(self):
+        creds = self.get_user_creds()
+        creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+
+        lp = self.get_loadparm()
+        lp.set('client ipc max protocol', 'NT1')
+        lp.set('client ipc min protocol', 'NT1')
+
+        binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')))
+        self.assertRaises(NTSTATUSError, lsa.lsarpc, binding_string, lp, creds)
diff --git a/selftest/tests.py b/selftest/tests.py
index 20981754db4..adcb5b53189 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -92,6 +92,7 @@ planpythontestsuite(
     extra_path=[os.path.join(samba4srcdir, "..", "buildtools"),
                 os.path.join(samba4srcdir, "..", "third_party", "waf")])
 planpythontestsuite("fileserver", "samba.tests.smbd_fuzztest")
+planpythontestsuite("nt4_dc_smb1", "samba.tests.dcerpc.binding")
 
 
 def cmdline(script, *args):
-- 
2.29.2


From fefa1d0236c67b2a93328eb9e0eac21da22235b2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 4 Sep 2020 10:47:54 +0200
Subject: [PATCH 050/104] auth:gensec: Add gensec_security_sasl_names()

Pair-Programmed-With: Andreas Schneider <asn@samba.org>

Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit b34e8dc8982b625d946e2ac8794ee41311bc41c2)
---
 auth/gensec/gensec.h       |  2 +
 auth/gensec/gensec_start.c | 87 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+)

diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h
index d424067d02c..fe26fff171a 100644
--- a/auth/gensec/gensec.h
+++ b/auth/gensec/gensec.h
@@ -308,6 +308,8 @@ const struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx
 
 NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
 					const char *sasl_name);
+const char **gensec_security_sasl_names(struct gensec_security *gensec_security,
+					TALLOC_CTX *mem_ctx);
 
 int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value);
 bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value);
diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index d2d62d6652e..4eb45643714 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -299,6 +299,93 @@ const struct gensec_security_ops *gensec_security_by_name(struct gensec_security
 	return NULL;
 }
 
+static const char **gensec_security_sasl_names_from_ops(
+	struct gensec_security *gensec_security,
+	TALLOC_CTX *mem_ctx,
+	const struct gensec_security_ops * const *ops)
+{
+	const char **sasl_names = NULL;
+	size_t i, sasl_names_count = 0;
+
+	if (ops == NULL) {
+		return NULL;
+	}
+
+	sasl_names = talloc_array(mem_ctx, const char *, 1);
+	if (sasl_names == NULL) {
+		return NULL;
+	}
+
+	for (i = 0; ops[i] != NULL; i++) {
+		enum gensec_role role = GENSEC_SERVER;
+		const char **tmp = NULL;
+
+		if (ops[i]->sasl_name == NULL) {
+			continue;
+		}
+
+		if (gensec_security != NULL) {
+			if (!gensec_security_ops_enabled(ops[i],
+							 gensec_security)) {
+				continue;
+			}
+
+			role = gensec_security->gensec_role;
+		}
+
+		switch (role) {
+		case GENSEC_CLIENT:
+			if (ops[i]->client_start == NULL) {
+				continue;
+			}
+			break;
+		case GENSEC_SERVER:
+			if (ops[i]->server_start == NULL) {
+				continue;
+			}
+			break;
+		}
+
+		tmp = talloc_realloc(mem_ctx,
+				     sasl_names,
+				     const char *,
+				     sasl_names_count + 2);
+		if (tmp == NULL) {
+			TALLOC_FREE(sasl_names);
+			return NULL;
+		}
+		sasl_names = tmp;
+
+		sasl_names[sasl_names_count] = ops[i]->sasl_name;
+		sasl_names_count++;
+	}
+	sasl_names[sasl_names_count] = NULL;
+
+	return sasl_names;
+}
+
+/**
+ * @brief Get the sasl names from the gensec security context.
+ *
+ * @param[in]  gensec_security The gensec security context.
+ *
+ * @param[in]  mem_ctx The memory context to allocate memory on.
+ *
+ * @return An allocated array with sasl names, NULL on error.
+ */
+_PUBLIC_
+const char **gensec_security_sasl_names(struct gensec_security *gensec_security,
+					TALLOC_CTX *mem_ctx)
+{
+	const struct gensec_security_ops **ops = NULL;
+
+	ops = gensec_security_mechs(gensec_security, mem_ctx);
+
+	return gensec_security_sasl_names_from_ops(gensec_security,
+						   mem_ctx,
+						   ops);
+}
+
 /**
  * Return a unique list of security subsystems from those specified in
  * the list of SASL names.
-- 
2.29.2


From adf58a175cea99c0b0147d3b3275563c7155edfa Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 4 Sep 2020 10:48:27 +0200
Subject: [PATCH 051/104] s4:ldap_server: Use samba_server_gensec_start() in
 ldapsrv_backend_Init()

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 5e3363e0b82193700f91a9bae5080aae0b744e5c)
---
 source4/dsdb/samdb/ldb_modules/rootdse.c |  4 +-
 source4/ldap_server/ldap_backend.c       | 49 +++++++++++-------------
 2 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 55340fa4f1e..4be9550747c 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -230,7 +230,7 @@ static int rootdse_add_dynamic(struct rootdse_context *ac, struct ldb_message *m
 	struct ldb_context *ldb;
 	struct rootdse_private_data *priv = talloc_get_type(ldb_module_get_private(ac->module), struct rootdse_private_data);
 	const char * const *attrs = ac->req->op.search.attrs;
-	char **server_sasl;
+	const char **server_sasl = NULL;
 	const struct dsdb_schema *schema;
 	int *val;
 	struct ldb_control *edn_control;
@@ -341,7 +341,7 @@ static int rootdse_add_dynamic(struct rootdse_context *ac, struct ldb_message *m
 	}
 
 	server_sasl = talloc_get_type(ldb_get_opaque(ldb, "supportedSASLMechanisms"),
-				       char *);
+				       const char *);
 	if (server_sasl && do_attribute(attrs, "supportedSASLMechanisms")) {
 		for (i = 0; server_sasl && server_sasl[i]; i++) {
 			char *sasl_name = talloc_strdup(msg, server_sasl[i]);
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index 2839082daef..915d9b94f9b 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -33,6 +33,7 @@
 #include "ldb_wrap.h"
 #include "lib/tsocket/tsocket.h"
 #include "libcli/ldap/ldap_proto.h"
+#include "source4/auth/auth.h"
 
 static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err,
 	const char *add_err_string, const char **errstring)
@@ -199,37 +200,33 @@ int ldapsrv_backend_Init(struct ldapsrv_connection *conn,
 	}
 
 	if (conn->server_credentials) {
-		char **sasl_mechs = NULL;
-		const struct gensec_security_ops * const *backends = gensec_security_all();
-		const struct gensec_security_ops **ops
-			= gensec_use_kerberos_mechs(conn, backends, conn->server_credentials);
-		unsigned int i, j = 0;
-		for (i = 0; ops && ops[i]; i++) {
-			if (!lpcfg_parm_bool(conn->lp_ctx,  NULL, "gensec", ops[i]->name, ops[i]->enabled))
-				continue;
-
-			if (ops[i]->sasl_name && ops[i]->server_start) {
-				char *sasl_name = talloc_strdup(conn, ops[i]->sasl_name);
-
-				if (!sasl_name) {
-					return LDB_ERR_OPERATIONS_ERROR;
-				}
-				sasl_mechs = talloc_realloc(conn, sasl_mechs, char *, j + 2);
-				if (!sasl_mechs) {
-					return LDB_ERR_OPERATIONS_ERROR;
-				}
-				sasl_mechs[j] = sasl_name;
-				talloc_steal(sasl_mechs, sasl_name);
-				sasl_mechs[j+1] = NULL;
-				j++;
-			}
+		struct gensec_security *gensec_security = NULL;
+		const char **sasl_mechs = NULL;
+		NTSTATUS status;
+
+		status = samba_server_gensec_start(conn,
+						   conn->connection->event.ctx,
+						   conn->connection->msg_ctx,
+						   conn->lp_ctx,
+						   conn->server_credentials,
+						   "ldap",
+						   &gensec_security);
+		if (!NT_STATUS_IS_OK(status)) {
+			DBG_ERR("samba_server_gensec_start failed: %s\n",
+				nt_errstr(status));
+			return LDB_ERR_OPERATIONS_ERROR;
 		}
-		talloc_unlink(conn, ops);
 
 		/* ldb can have a different lifetime to conn, so we
 		   need to ensure that sasl_mechs lives as long as the
 		   ldb does */
-		talloc_steal(conn->ldb, sasl_mechs);
+		sasl_mechs = gensec_security_sasl_names(gensec_security,
+							conn->ldb);
+		TALLOC_FREE(gensec_security);
+		if (sasl_mechs == NULL) {
+			DBG_ERR("Failed to get sasl mechs!\n");
+			return LDB_ERR_OPERATIONS_ERROR;
+		}
 
 		ldb_set_opaque(conn->ldb, "supportedSASLMechanisms", sasl_mechs);
 	}
-- 
2.29.2


From e887d94b47aca3609fd158efe0f4654101c5e02b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 4 Sep 2020 14:39:15 +0200
Subject: [PATCH 052/104] auth:gensec: Make gensec_use_kerberos_mechs() a
 static function

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 2186d4131ad4c7961d0c830bf9d48f3d06d27924)
---
 auth/gensec/gensec.h       | 3 ---
 auth/gensec/gensec_start.c | 7 ++++---
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h
index fe26fff171a..8bece3c3458 100644
--- a/auth/gensec/gensec.h
+++ b/auth/gensec/gensec.h
@@ -302,9 +302,6 @@ NTSTATUS gensec_wrap(struct gensec_security *gensec_security,
 
 const struct gensec_security_ops * const *gensec_security_all(void);
 bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct gensec_security *security);
-const struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx,
-			const struct gensec_security_ops * const *old_gensec_list,
-			struct cli_credentials *creds);
 
 NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security,
 					const char *sasl_name);
diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index 4eb45643714..ebcab76999a 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -83,9 +83,10 @@ bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct g
  * more compplex.
  */
 
-_PUBLIC_ const struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx,
-			const struct gensec_security_ops * const *old_gensec_list,
-			struct cli_credentials *creds)
+static const struct gensec_security_ops **gensec_use_kerberos_mechs(
+		TALLOC_CTX *mem_ctx,
+		const struct gensec_security_ops * const *old_gensec_list,
+		struct cli_credentials *creds)
 {
 	const struct gensec_security_ops **new_gensec_list;
 	int i, j, num_mechs_in;
-- 
2.29.2


From 08dc4775dbf72a1e8068d392360be158d8305bfa Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 4 Sep 2020 14:41:43 +0200
Subject: [PATCH 053/104] auth:gensec: Pass use_kerberos and keep_schannel to
 gensec_use_kerberos_mechs()

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit a33a40bbc848e5691869cf264009d23a03128f31)
---
 auth/gensec/gensec_start.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index ebcab76999a..8d1b41fec74 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -86,19 +86,11 @@ bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct g
 static const struct gensec_security_ops **gensec_use_kerberos_mechs(
 		TALLOC_CTX *mem_ctx,
 		const struct gensec_security_ops * const *old_gensec_list,
-		struct cli_credentials *creds)
+		enum credentials_use_kerberos use_kerberos,
+		bool keep_schannel)
 {
 	const struct gensec_security_ops **new_gensec_list;
 	int i, j, num_mechs_in;
-	enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS;
-	bool keep_schannel = false;
-
-	if (creds) {
-		use_kerberos = cli_credentials_get_kerberos_state(creds);
-		if (cli_credentials_get_netlogon_creds(creds) != NULL) {
-			keep_schannel = true;
-		}
-	}
 
 	for (num_mechs_in=0; old_gensec_list && old_gensec_list[num_mechs_in]; num_mechs_in++) {
 		/* noop */
@@ -163,18 +155,28 @@ _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs(
 				struct gensec_security *gensec_security,
 				TALLOC_CTX *mem_ctx)
 {
-	struct cli_credentials *creds = NULL;
 	const struct gensec_security_ops * const *backends = gensec_security_all();
+	enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS;
+	bool keep_schannel = false;
 
 	if (gensec_security != NULL) {
+		struct cli_credentials *creds = NULL;
+
 		creds = gensec_get_credentials(gensec_security);
+		if (creds != NULL) {
+			use_kerberos = cli_credentials_get_kerberos_state(creds);
+			if (cli_credentials_get_netlogon_creds(creds) != NULL) {
+				keep_schannel = true;
+			}
+		}
 
 		if (gensec_security->settings->backends) {
 			backends = gensec_security->settings->backends;
 		}
 	}
 
-	return gensec_use_kerberos_mechs(mem_ctx, backends, creds);
+	return gensec_use_kerberos_mechs(mem_ctx, backends,
+					 use_kerberos, keep_schannel);
 
 }
 
-- 
2.29.2


From bc505a449449267085778ec51c5362e256837edb Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze@samba.org>
Date: Fri, 4 Sep 2020 17:00:45 +0200
Subject: [PATCH 054/104] auth:gensec: If Kerberos is required, keep schannel
 for machine account auth

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 515cffb1f20eacb041ff7b3d43f8a122a82ddfbd)
---
 auth/gensec/gensec_start.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index 8d1b41fec74..3f42d611140 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -168,6 +168,15 @@ _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs(
 			if (cli_credentials_get_netlogon_creds(creds) != NULL) {
 				keep_schannel = true;
 			}
+
+			/*
+			 * Even if Kerberos is set to REQUIRED, keep the
+			 * schannel auth mechanism that machine accounts are
+			 * able to authenticate via netlogon.
+			 */
+			if (gensec_security->gensec_role == GENSEC_SERVER) {
+				keep_schannel = true;
+			}
 		}
 
 		if (gensec_security->settings->backends) {
-- 
2.29.2


From 9b7a189e038e3f783a2b23302f0ee4657ef18057 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 4 Sep 2020 12:21:21 +0200
Subject: [PATCH 055/104] auth:creds: Add cli_credentials_init_server()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 2c00bea2aefdcc69608dffdafa7ce581d31f9354)
---
 auth/credentials/credentials.c | 25 +++++++++++++++++++++++++
 auth/credentials/credentials.h |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 9168b92d3ec..77c35dd104b 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -56,6 +56,31 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 	return cred;
 }
 
+_PUBLIC_
+struct cli_credentials *cli_credentials_init_server(TALLOC_CTX *mem_ctx,
+						    struct loadparm_context *lp_ctx)
+{
+	struct cli_credentials *server_creds = NULL;
+	NTSTATUS status;
+
+	server_creds = cli_credentials_init(mem_ctx);
+	if (server_creds == NULL) {
+		return NULL;
+	}
+
+	cli_credentials_set_conf(server_creds, lp_ctx);
+
+	status = cli_credentials_set_machine_account(server_creds, lp_ctx);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Failed to obtain server credentials: %s\n",
+			  nt_errstr(status)));
+		TALLOC_FREE(server_creds);
+		return NULL;
+	}
+
+	return server_creds;
+}
+
 _PUBLIC_ void cli_credentials_set_callback_data(struct cli_credentials *cred,
 						void *callback_data)
 {
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 7d0cf53194b..438bcdce232 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -76,6 +76,8 @@ bool cli_credentials_set_workstation(struct cli_credentials *cred,
 				     enum credentials_obtained obtained);
 bool cli_credentials_is_anonymous(struct cli_credentials *cred);
 struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx);
+struct cli_credentials *cli_credentials_init_server(TALLOC_CTX *mem_ctx,
+						    struct loadparm_context *lp_ctx);
 void cli_credentials_set_anonymous(struct cli_credentials *cred);
 bool cli_credentials_wrong_password(struct cli_credentials *cred);
 const char *cli_credentials_get_password(struct cli_credentials *cred);
-- 
2.29.2


From 013d5eb87f3ddcda6df5c76796bede7a85c42207 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 4 Sep 2020 12:21:36 +0200
Subject: [PATCH 056/104] s4:rpc_server: Use cli_credentials_init_server()

Signed-off-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 6c94ebf77fdb7383be2042f5e20ba2ef598cd4a4)
---
 source4/rpc_server/dcerpc_server.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index 084857a44bf..e64148ef788 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -673,25 +673,14 @@ NTSTATUS dcesrv_gensec_prepare(TALLOC_CTX *mem_ctx,
 	struct cli_credentials *server_creds = NULL;
 	struct imessaging_context *imsg_ctx =
 		dcesrv_imessaging_context(call->conn);
-	NTSTATUS status;
 
-	server_creds = cli_credentials_init(call->auth_state);
-	if (!server_creds) {
+	server_creds = cli_credentials_init_server(call->auth_state,
+						   call->conn->dce_ctx->lp_ctx);
+	if (server_creds == NULL) {
 		DEBUG(1, ("Failed to init server credentials\n"));
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	cli_credentials_set_conf(server_creds, call->conn->dce_ctx->lp_ctx);
-
-	status = cli_credentials_set_machine_account(server_creds,
-						call->conn->dce_ctx->lp_ctx);
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("Failed to obtain server credentials: %s\n",
-			  nt_errstr(status)));
-		talloc_free(server_creds);
-		return status;
-	}
-
 	return samba_server_gensec_start(mem_ctx,
 					 call->event_ctx,
 					 imsg_ctx,
-- 
2.29.2


From 6e6030dca006e829150e6b64db0485e3c9895485 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 7 Sep 2020 09:19:43 +0200
Subject: [PATCH 057/104] s4:smb_server: Use cli_credentials_init_server() for
 negprot

Signed-off-by: Andreas Schneider <asn@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Mon Sep  7 13:22:26 UTC 2020 on sn-devel-184

(cherry picked from commit 0b742ec6a0558397d5cf01b99a401f8e2bc0e2e0)
---
 source4/smb_server/smb/negprot.c  | 28 ++++++++++++++--------------
 source4/smb_server/smb2/negprot.c | 25 +++++++++++++------------
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c
index a6177a72019..04b69dd9883 100644
--- a/source4/smb_server/smb/negprot.c
+++ b/source4/smb_server/smb/negprot.c
@@ -374,22 +374,22 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
 		DATA_BLOB blob = data_blob_null;
 		const char *oid;
 		NTSTATUS nt_status;
-		
-		server_credentials 
-			= cli_credentials_init(req);
-		if (!server_credentials) {
-			smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n");
-			return;
-		}
-		
-		cli_credentials_set_conf(server_credentials, req->smb_conn->lp_ctx);
-		nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx);
-		if (!NT_STATUS_IS_OK(nt_status)) {
-			DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status)));
+
+		server_credentials =
+			cli_credentials_init_server(req, req->smb_conn->lp_ctx);
+		if (server_credentials == NULL) {
+			DBG_DEBUG("Failed to obtain server credentials, "
+				  "perhaps a standalone server?\n");
 			/*
-			 * We keep the server_credentials as anonymous
-			 * this is required for the spoolss.notify test
+			 * Create anon server credentials for for the
+			 * spoolss.notify test.
 			 */
+			server_credentials = cli_credentials_init_anon(req);
+			if (server_credentials == NULL) {
+				smbsrv_terminate_connection(req->smb_conn,
+					"Failed to init server credentials\n");
+				return;
+			}
 		}
 
 		nt_status = samba_server_gensec_start(req,
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index 4aaaf46793b..c433eb194bd 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -39,20 +39,21 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB *
 	NTSTATUS nt_status;
 	struct cli_credentials *server_credentials;
 
-	server_credentials = cli_credentials_init(req);
-	if (!server_credentials) {
-		smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n");
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	cli_credentials_set_conf(server_credentials, req->smb_conn->lp_ctx);
-	nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status)));
+	server_credentials =
+		cli_credentials_init_server(req, req->smb_conn->lp_ctx);
+	if (server_credentials == NULL) {
+		DBG_DEBUG("Failed to obtain server credentials, "
+			  "perhaps a standalone server?\n");
 		/*
-		 * We keep the server_credentials as anonymous
-		 * this is required for the spoolss.notify test
+		 * Create anon server credentials for for the
+		 * spoolss.notify test.
 		 */
+		server_credentials = cli_credentials_init_anon(req);
+		if (server_credentials == NULL) {
+			smbsrv_terminate_connection(req->smb_conn,
+				"Failed to init server credentials\n");
+			return NT_STATUS_NO_MEMORY;
+		}
 	}
 
 	req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials);
-- 
2.29.2


From f9f25b7690c2e234ea2e631f05c1fb0180776842 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 8 Sep 2020 10:15:22 +0200
Subject: [PATCH 058/104] selftest: Rename 'smb encrypt' to 'server smb
 encrypt'

This makes it more clear what we want. 'smb encrypt' is a synonym for
'server smb encrypt'.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit c75e8ff47b4d79b37240f9461ddae10a4f03c892)
---
 selftest/target/Samba3.pm | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index e141f102ef1..c070086ca49 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1178,7 +1178,7 @@ sub setup_simpleserver
 	ntlm auth = yes
 	vfs objects = xattr_tdb streams_depot
 	change notify = no
-	smb encrypt = off
+	server smb encrypt = off
 
 [vfs_aio_pthread]
 	path = $prefix_abs/share
@@ -1245,7 +1245,7 @@ sub setup_simpleserver
 [enc_desired]
 	path = $prefix_abs/share
 	vfs objects =
-	smb encrypt = desired
+	server smb encrypt = desired
 
 [hidenewfiles]
 	path = $prefix_abs/share
@@ -2351,7 +2351,7 @@ sub provision($$)
 [tmpenc]
 	path = $shrdir
 	comment = encrypt smb username is [%U]
-	smb encrypt = required
+	server smb encrypt = required
 	vfs objects = dirsort
 [tmpguest]
 	path = $shrdir
-- 
2.29.2


From 2fc16a8d11f48424fc2fff0380fb623f552ece5f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 8 Sep 2020 12:30:08 +0200
Subject: [PATCH 059/104] selftest: Move enc_desired to provision to have it in
 'fileserver' too

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 1b67943f938ae774360dc3db73db940f9982243b)
---
 selftest/target/Samba3.pm | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index c070086ca49..fa3ca8962a5 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -1242,11 +1242,6 @@ sub setup_simpleserver
 	hide files = /hidefile/
 	hide dot files = yes
 
-[enc_desired]
-	path = $prefix_abs/share
-	vfs objects =
-	server smb encrypt = desired
-
 [hidenewfiles]
 	path = $prefix_abs/share
 	hide new files timeout = 5
@@ -2833,7 +2828,13 @@ sub provision($$)
 [delete_readonly]
 	path = $prefix_abs/share
 	delete readonly = yes
+
+[enc_desired]
+	path = $prefix_abs/share
+	vfs objects =
+	server smb encrypt = desired
 	";
+
 	close(CONF);
 
 	my $net = Samba::bindir_path($self, "net");
-- 
2.29.2


From 299d7d6868e9590693e465cbc0c10abe8b7fc5a0 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 8 Sep 2020 10:15:20 +0200
Subject: [PATCH 060/104] s3:tests: Add smbclient tests for 'client smb
 encrypt'

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit e7577ab6cbc83b496ac091c3e425c7c7fea29cdb)
---
 selftest/knownfail.d/smbclient-encryption     |  2 +
 selftest/target/Samba3.pm                     |  5 ++
 .../script/tests/test_smbclient_encryption.sh | 72 +++++++++++++++++++
 source3/selftest/tests.py                     |  6 ++
 4 files changed, 85 insertions(+)
 create mode 100644 selftest/knownfail.d/smbclient-encryption
 create mode 100755 source3/script/tests/test_smbclient_encryption.sh

diff --git a/selftest/knownfail.d/smbclient-encryption b/selftest/knownfail.d/smbclient-encryption
new file mode 100644
index 00000000000..972096bdc8b
--- /dev/null
+++ b/selftest/knownfail.d/smbclient-encryption
@@ -0,0 +1,2 @@
+^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.enc_desired..simpleserver
+^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.tmp..simpleserver
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index fa3ca8962a5..ffc19c7d5a2 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -2833,6 +2833,11 @@ sub provision($$)
 	path = $prefix_abs/share
 	vfs objects =
 	server smb encrypt = desired
+
+[enc_off]
+	path = $prefix_abs/share
+	vfs objects =
+	server smb encrypt = off
 	";
 
 	close(CONF);
diff --git a/source3/script/tests/test_smbclient_encryption.sh b/source3/script/tests/test_smbclient_encryption.sh
new file mode 100755
index 00000000000..9a717cdac4f
--- /dev/null
+++ b/source3/script/tests/test_smbclient_encryption.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+if [ $# -lt 5 ]; then
+cat <<EOF
+Usage: test_smbclient_encryption.sh USERNAME PASSWORD SERVER SMBCLIENT TARGET
+EOF
+exit 1;
+fi
+
+USERNAME="$1"
+PASSWORD="$2"
+SERVER="$3"
+SMBCLIENT="$VALGRIND $4"
+TARGET="$5"
+shift 5
+
+incdir=`dirname $0`/../../../testprogs/blackbox
+. $incdir/subunit.sh
+
+failed=0
+
+#
+# Server configuration for fileserver:
+# 
+# global: 'server smb encrypt = default'
+# enc_desired: 'server smb encrypt = desired'
+# tmpenc: 'server smb encrypt = required'
+# tmp: has the global default 'server smb encrypt'
+#
+# Server configuration for simpleserver:
+# 
+# global: 'server smb encrypt = off'
+# enc_desired: 'server smb encrypt = desired'
+# tmpenc: 'server smb encrypt = required'
+# tmp: has the global default 'server smb encrypt'
+#
+
+testit "smbclient.smb3.client.encrypt.desired[//$SERVER/enc_desired]" $SMBCLIENT //$SERVER/enc_desired -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=desired -c 'ls; quit' || failed=`expr $failed + 1`
+if [ "$TARGET" = "fileserver" ]; then
+    testit "smbclient.smb3.client.encrypt.desired[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=desired -c 'ls; quit' || failed=`expr $failed + 1`
+elif [ "$TARGET" = "simpleserver" ]; then # Encryption is globally disabled
+    testit_expect_failure "smbclient.smb3.client.encrypt.desired[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=desired -c 'ls; quit' || failed=`expr $failed + 1`
+fi
+testit "smbclient.smb3.client.encrypt.desired[//$SERVER/tmp]" $SMBCLIENT //$SERVER/tmp -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=desired -c 'ls; quit' || failed=`expr $failed + 1`
+
+testit "smbclient.smb3.client.encrypt.if_required[//$SERVER/enc_desired]" $SMBCLIENT //$SERVER/enc_desired -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=if_required -c 'ls; quit' || failed=`expr $failed + 1`
+if [ "$TARGET" = "fileserver" ]; then
+    testit "smbclient.smb3.client.encrypt.if_required[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=if_required -c 'ls; quit' || failed=`expr $failed + 1`
+elif [ "$TARGET" = "simpleserver" ]; then # Encryption is globally disabled
+    testit_expect_failure "smbclient.smb3.client.encrypt.if_required[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=if_required -c 'ls; quit' || failed=`expr $failed + 1`
+fi
+testit "smbclient.smb3.client.encrypt.if_required[//$SERVER/tmp]" $SMBCLIENT //$SERVER/tmp -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=if_required -c 'ls; quit' || failed=`expr $failed + 1`
+
+if [ "$TARGET" = "fileserver" ]; then
+    testit "smbclient.smb3.client.encrypt.required[//$SERVER/enc_desired]" $SMBCLIENT //$SERVER/enc_desired -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=required -c 'ls; quit' || failed=`expr $failed + 1`
+    testit "smbclient.smb3.client.encrypt.required[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=required -c 'ls; quit' || failed=`expr $failed + 1`
+    testit "smbclient.smb3.client.encrypt.required[//$SERVER/tmp]" $SMBCLIENT //$SERVER/tmp -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=required -c 'ls; quit' || failed=`expr $failed + 1`
+elif [ "$TARGET" = "simpleserver" ]; then # Encryption is globally disabled
+    testit_expect_failure "smbclient.smb3.client.encrypt.required[//$SERVER/enc_desired]" $SMBCLIENT //$SERVER/enc_desired -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=required -c 'ls; quit' || failed=`expr $failed + 1`
+    testit_expect_failure "smbclient.smb3.client.encrypt.required[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=required -c 'ls; quit' || failed=`expr $failed + 1`
+    testit_expect_failure "smbclient.smb3.client.encrypt.required[//$SERVER/tmp]" $SMBCLIENT //$SERVER/tmp -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=required -c 'ls; quit' || failed=`expr $failed + 1`
+fi
+
+testit "smbclient.smb3.client.encrypt.off[//$SERVER/enc_desired]" $SMBCLIENT //$SERVER/enc_desired -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=off -c 'ls; quit' || failed=`expr $failed + 1`
+if [ "$TARGET" = "fileserver" ]; then
+    testit "smbclient.smb3.client.encrypt.off[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=off -c 'ls; quit' || failed=`expr $failed + 1`
+elif [ "$TARGET" = "simpleserver" ]; then # Encryption is globally disabled
+    testit_expect_failure "smbclient.smb3.client.encrypt.off[//$SERVER/tmpenc]" $SMBCLIENT //$SERVER/tmpenc -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=off -c 'ls; quit' || failed=`expr $failed + 1`
+fi
+testit "smbclient.smb3.client.encrypt.off[//$SERVER/tmp]" $SMBCLIENT //$SERVER/tmp -U$USERNAME%$PASSWORD -mSMB3 --option=clientsmbencrypt=off -c 'ls; quit' || failed=`expr $failed + 1`
+
+testok $0 $failed
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 27dc7587b17..46bf274227c 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -1040,6 +1040,12 @@ plantestsuite("samba3.blackbox.smbclient.encryption_off", "simpleserver",
                "$USERNAME", "$PASSWORD", "$SERVER",
                smbclient3])
 
+for env in ['fileserver', 'simpleserver']:
+    plantestsuite("samba3.blackbox.smbclient.encryption", env,
+                  [os.path.join(samba3srcdir, "script/tests/test_smbclient_encryption.sh"),
+                   "$USERNAME", "$PASSWORD", "$SERVER",
+                   smbclient3, env])
+
 plantestsuite("samba3.blackbox.rpcclient_netsessenum", "ad_member",
               [os.path.join(samba3srcdir,
                             "script/tests/test_rpcclient_netsessenum.sh"),
-- 
2.29.2


From d996ccf7dc53046f92827ddab72aac6e92dd3a77 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 15:19:27 +0200
Subject: [PATCH 061/104] s3:client: Remove global smb_encrypt

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 1189b20cb7ea09cfed5c246cf977442a51ef72cb)
---
 source3/client/client.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/source3/client/client.c b/source3/client/client.c
index 56309efcea7..60d4fb3c5ee 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -96,9 +96,6 @@ static unsigned int put_total_time_ms = 0;
 /* totals globals */
 static double dir_total;
 
-/* encrypted state. */
-static bool smb_encrypt;
-
 /* root cli_state connection */
 
 struct cli_state *cli;
@@ -2758,7 +2755,7 @@ static int cmd_posix_encrypt(void)
 		d_printf("posix_encrypt failed with error %s\n", nt_errstr(status));
 	} else {
 		d_printf("encryption on\n");
-		smb_encrypt = true;
+		set_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info());
 	}
 
 	return 0;
@@ -5283,6 +5280,9 @@ int cmd_iosize(void)
 	TALLOC_CTX *ctx = talloc_tos();
 	char *buf;
 	int iosize;
+	bool smb_encrypt =
+		get_cmdline_auth_info_smb_encrypt(
+				popt_get_cmdline_auth_info());
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
 		if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
@@ -5546,6 +5546,9 @@ static int process_command_string(const char *cmd_in)
 	TALLOC_CTX *ctx = talloc_tos();
 	char *cmd = talloc_strdup(ctx, cmd_in);
 	int rc = 0;
+	bool smb_encrypt =
+		get_cmdline_auth_info_smb_encrypt(
+				popt_get_cmdline_auth_info());
 
 	if (!cmd) {
 		return 1;
@@ -5999,6 +6002,9 @@ static int process(const char *base_directory)
 {
 	int rc = 0;
 	NTSTATUS status;
+	bool smb_encrypt =
+		get_cmdline_auth_info_smb_encrypt(
+				popt_get_cmdline_auth_info());
 
 	status = cli_cm_open(talloc_tos(), NULL,
 			     desthost,
@@ -6037,6 +6043,9 @@ static int process(const char *base_directory)
 static int do_host_query(const char *query_host)
 {
 	NTSTATUS status;
+	bool smb_encrypt =
+		get_cmdline_auth_info_smb_encrypt(
+				popt_get_cmdline_auth_info());
 
 	status = cli_cm_open(talloc_tos(), NULL,
 			     query_host,
@@ -6114,6 +6123,9 @@ static int do_tar_op(const char *base_directory)
 {
 	struct tar *tar_ctx = tar_get_ctx();
 	int ret = 0;
+	bool smb_encrypt =
+		get_cmdline_auth_info_smb_encrypt(
+				popt_get_cmdline_auth_info());
 
 	/* do we already have a connection? */
 	if (!cli) {
@@ -6459,9 +6471,6 @@ int main(int argc,char *argv[])
 		case 'q':
 			quiet=true;
 			break;
-		case 'e':
-			smb_encrypt=true;
-			break;
 		case 'B':
 			return(do_smb_browse());
 
@@ -6531,8 +6540,6 @@ int main(int argc,char *argv[])
 
 	/* Ensure we have a password (or equivalent). */
 	popt_common_credentials_post();
-	smb_encrypt = get_cmdline_auth_info_smb_encrypt(
-			popt_get_cmdline_auth_info());
 
 	max_protocol = lp_client_max_protocol();
 
-- 
2.29.2


From b923ea7625de03e23a999a3cb844d81dcd25316f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 15:24:27 +0200
Subject: [PATCH 062/104] s3:libsmb: Remove force_encrypt from cli_cm_open()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit a9fbc8dae878ddfa54153e91cc1128c307816b76)
---
 source3/client/client.c | 21 ++++-----------------
 source3/lib/netapi/cm.c |  1 -
 source3/libsmb/clidfs.c |  4 ++--
 source3/libsmb/proto.h  |  1 -
 4 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/source3/client/client.c b/source3/client/client.c
index 60d4fb3c5ee..3a610086511 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -5546,9 +5546,6 @@ static int process_command_string(const char *cmd_in)
 	TALLOC_CTX *ctx = talloc_tos();
 	char *cmd = talloc_strdup(ctx, cmd_in);
 	int rc = 0;
-	bool smb_encrypt =
-		get_cmdline_auth_info_smb_encrypt(
-				popt_get_cmdline_auth_info());
 
 	if (!cmd) {
 		return 1;
@@ -5561,7 +5558,6 @@ static int process_command_string(const char *cmd_in)
 		status = cli_cm_open(talloc_tos(), NULL,
 				     desthost,
 				     service, popt_get_cmdline_auth_info(),
-				     smb_encrypt,
 				     max_protocol,
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type,
@@ -6002,14 +5998,11 @@ static int process(const char *base_directory)
 {
 	int rc = 0;
 	NTSTATUS status;
-	bool smb_encrypt =
-		get_cmdline_auth_info_smb_encrypt(
-				popt_get_cmdline_auth_info());
 
 	status = cli_cm_open(talloc_tos(), NULL,
 			     desthost,
 			     service, popt_get_cmdline_auth_info(),
-			     smb_encrypt, max_protocol,
+			     max_protocol,
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -6043,14 +6036,11 @@ static int process(const char *base_directory)
 static int do_host_query(const char *query_host)
 {
 	NTSTATUS status;
-	bool smb_encrypt =
-		get_cmdline_auth_info_smb_encrypt(
-				popt_get_cmdline_auth_info());
 
 	status = cli_cm_open(talloc_tos(), NULL,
 			     query_host,
 			     "IPC$", popt_get_cmdline_auth_info(),
-			     smb_encrypt, max_protocol,
+			     max_protocol,
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -6097,7 +6087,7 @@ static int do_host_query(const char *query_host)
 		status = cli_cm_open(talloc_tos(), NULL,
 				     query_host,
 				     "IPC$", popt_get_cmdline_auth_info(),
-				     smb_encrypt, max_proto,
+				     max_proto,
 				     have_ip ? &dest_ss : NULL, NBT_SMB_PORT,
 				     name_type, &cli);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -6123,9 +6113,6 @@ static int do_tar_op(const char *base_directory)
 {
 	struct tar *tar_ctx = tar_get_ctx();
 	int ret = 0;
-	bool smb_encrypt =
-		get_cmdline_auth_info_smb_encrypt(
-				popt_get_cmdline_auth_info());
 
 	/* do we already have a connection? */
 	if (!cli) {
@@ -6134,7 +6121,7 @@ static int do_tar_op(const char *base_directory)
 		status = cli_cm_open(talloc_tos(), NULL,
 				     desthost,
 				     service, popt_get_cmdline_auth_info(),
-				     smb_encrypt, max_protocol,
+				     max_protocol,
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type, &cli);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index 1b8f2a4e97a..0fd31ef3d5a 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -110,7 +110,6 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
 	status = cli_cm_open(ctx, NULL,
 			     server_name, "IPC$",
 			     auth_info,
-			     false,
 			     lp_client_ipc_max_protocol(),
 			     NULL, 0, 0x20, &cli_ipc);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index aff998f6187..4825b8f3fae 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -383,7 +383,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				const char *server,
 				const char *share,
 				const struct user_auth_info *auth_info,
-				bool force_encrypt,
 				int max_protocol,
 				const struct sockaddr_storage *dest_ss,
 				int port,
@@ -393,6 +392,8 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 	/* Try to reuse an existing connection in this list. */
 	struct cli_state *c = cli_cm_find(referring_cli, server, share);
 	NTSTATUS status;
+	bool force_encrypt =
+		get_cmdline_auth_info_smb_encrypt(auth_info);
 
 	if (c) {
 		*pcli = c;
@@ -962,7 +963,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 			     smbXcli_conn_remote_name(rootcli->conn),
 			     "IPC$",
 			     dfs_auth_info,
-			     cli_state_is_encryption_on(rootcli),
 			     smbXcli_conn_protocol(rootcli->conn),
 			     NULL, /* dest_ss not needed, we reuse the transport */
 			     0,
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index eeabcaa7463..bb3e9e6874e 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -128,7 +128,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				const char *server,
 				const char *share,
 				const struct user_auth_info *auth_info,
-				bool force_encrypt,
 				int max_protocol,
 				const struct sockaddr_storage *dest_ss,
 				int port,
-- 
2.29.2


From 2fd26f4c208556cd2f28f0c54fe11cea044c7881 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 15:26:39 +0200
Subject: [PATCH 063/104] s3:libsmb: Remove force_encrypt from cli_cm_connect()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit d27e237cf37fb254646d94827935d9c302c379ff)
---
 source3/libsmb/clidfs.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 4825b8f3fae..b0032005398 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -287,7 +287,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 			       const char *server,
 			       const char *share,
 			       const struct user_auth_info *auth_info,
-			       bool force_encrypt,
 			       int max_protocol,
 			       const struct sockaddr_storage *dest_ss,
 			       int port,
@@ -296,6 +295,8 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 {
 	struct cli_state *cli = NULL;
 	NTSTATUS status;
+	bool force_encrypt =
+		get_cmdline_auth_info_smb_encrypt(auth_info);
 
 	status = do_connect(ctx, server, share,
 				auth_info,
@@ -392,8 +393,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 	/* Try to reuse an existing connection in this list. */
 	struct cli_state *c = cli_cm_find(referring_cli, server, share);
 	NTSTATUS status;
-	bool force_encrypt =
-		get_cmdline_auth_info_smb_encrypt(auth_info);
 
 	if (c) {
 		*pcli = c;
@@ -414,7 +413,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				server,
 				share,
 				auth_info,
-				force_encrypt,
 				max_protocol,
 				dest_ss,
 				port,
@@ -1020,7 +1018,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 				dfs_refs[count].server,
 				dfs_refs[count].share,
 				dfs_auth_info,
-				cli_state_is_encryption_on(rootcli),
 				smbXcli_conn_protocol(rootcli->conn),
 				NULL, /* dest_ss */
 				0, /* port */
-- 
2.29.2


From 3db1056dc42765aa3043b6ea0fd0389a34a41145 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 15:28:28 +0200
Subject: [PATCH 064/104] s3:libsmb: Remove force_encrypt from clidfs
 do_connect()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 615a9a68166bdeb0ab7dbacf395c6125ec70f288)
---
 source3/libsmb/clidfs.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index b0032005398..5503506de97 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -107,7 +107,6 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 					const char *server,
 					const char *share,
 					const struct user_auth_info *auth_info,
-					bool force_encrypt,
 					int max_protocol,
 					const struct sockaddr_storage *dest_ss,
 					int port,
@@ -123,6 +122,8 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 	enum protocol_types protocol = PROTOCOL_NONE;
 	int signing_state = get_cmdline_auth_info_signing_state(auth_info);
 	struct cli_credentials *creds = NULL;
+	bool force_encrypt =
+		get_cmdline_auth_info_smb_encrypt(auth_info);
 
 	if (force_encrypt) {
 		signing_state = SMB_SIGNING_REQUIRED;
@@ -233,7 +234,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 		cli_shutdown(c);
 		return do_connect(ctx, newserver,
 				newshare, auth_info,
-				force_encrypt, max_protocol,
+				max_protocol,
 				NULL, port, name_type, pcli);
 	}
 
@@ -295,12 +296,10 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 {
 	struct cli_state *cli = NULL;
 	NTSTATUS status;
-	bool force_encrypt =
-		get_cmdline_auth_info_smb_encrypt(auth_info);
 
 	status = do_connect(ctx, server, share,
 				auth_info,
-				force_encrypt, max_protocol,
+				max_protocol,
 				dest_ss, port, name_type, &cli);
 
 	if (!NT_STATUS_IS_OK(status)) {
-- 
2.29.2


From 8b234932ec76052258078d08071c33fefd5f3a0e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 15:52:11 +0200
Subject: [PATCH 065/104] s3:libsmb: Remove force_encrypt from
 cli_check_msdfs_proxy()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 4ddec1ca257fff418847c5d1e83a3fb7cb5ade1a)
---
 source3/libsmb/clidfs.c        | 17 ++++++++++++-----
 source3/libsmb/libsmb_server.c |  4 ----
 source3/libsmb/proto.h         |  1 -
 3 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 5503506de97..736c565a7a8 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -230,7 +230,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 	if (smbXcli_conn_dfs_supported(c->conn) &&
 			cli_check_msdfs_proxy(ctx, c, sharename,
 				&newserver, &newshare,
-				force_encrypt, creds)) {
+				creds)) {
 		cli_shutdown(c);
 		return do_connect(ctx, newserver,
 				newshare, auth_info,
@@ -1176,7 +1176,6 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 				const char *sharename,
 				char **pp_newserver,
 				char **pp_newshare,
-				bool force_encrypt,
 				struct cli_credentials *creds)
 {
 	struct client_dfs_referral *refs = NULL;
@@ -1188,6 +1187,8 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 	char *newextrapath = NULL;
 	NTSTATUS status;
 	const char *remote_name;
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(creds);
 
 	if (!cli || !sharename) {
 		return false;
@@ -1223,11 +1224,17 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 		return false;
 	}
 
-	if (force_encrypt) {
+	if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
 		status = cli_cm_force_encryption_creds(cli, creds, "IPC$");
 		if (!NT_STATUS_IS_OK(status)) {
-			cli_state_restore_tcon(cli, orig_tcon);
-			return false;
+			switch (encryption_state) {
+			case SMB_ENCRYPTION_DESIRED:
+				break;
+			case SMB_ENCRYPTION_REQUIRED:
+			default:
+				cli_state_restore_tcon(cli, orig_tcon);
+				return false;
+			}
 		}
 	}
 
diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c
index eb58d7c6ac9..5a1055ba773 100644
--- a/source3/libsmb/libsmb_server.c
+++ b/source3/libsmb/libsmb_server.c
@@ -587,10 +587,6 @@ SMBC_server_internal(TALLOC_CTX *ctx,
 	if (smbXcli_conn_dfs_supported(c->conn) &&
 			cli_check_msdfs_proxy(ctx, c, share,
 				&newserver, &newshare,
-				/* FIXME: cli_check_msdfs_proxy() does
-				   not support smbc_smb_encrypt_level type */
-				context->internal->smb_encryption_level ?
-					true : false,
 				creds)) {
 		cli_shutdown(c);
 		srv = SMBC_server_internal(ctx, context, connect_if_not_found,
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index bb3e9e6874e..f2b0a8c5ff8 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -161,7 +161,6 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx,
 			const char *sharename,
 			char **pp_newserver,
 			char **pp_newshare,
-			bool force_encrypt,
 			struct cli_credentials *creds);
 
 /* The following definitions come from libsmb/clientgen.c  */
-- 
2.29.2


From b1324ba3361e66ca4bdf5b0cb0e1d8c8084955d4 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 18 Aug 2020 17:15:09 +0200
Subject: [PATCH 066/104] s3:libsmb: Pass cli_credentials to clidfs
 do_connect()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 276563de06f2071ec2ed9a8b73f92215ab621bba)
---
 selftest/knownfail.d/smbclient-encryption |  2 --
 source3/libsmb/clidfs.c                   | 34 +++++++++++++----------
 2 files changed, 20 insertions(+), 16 deletions(-)
 delete mode 100644 selftest/knownfail.d/smbclient-encryption

diff --git a/selftest/knownfail.d/smbclient-encryption b/selftest/knownfail.d/smbclient-encryption
deleted file mode 100644
index 972096bdc8b..00000000000
--- a/selftest/knownfail.d/smbclient-encryption
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.enc_desired..simpleserver
-^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.tmp..simpleserver
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 736c565a7a8..d536e0597af 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -106,7 +106,7 @@ static NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c,
 static NTSTATUS do_connect(TALLOC_CTX *ctx,
 					const char *server,
 					const char *share,
-					const struct user_auth_info *auth_info,
+					struct cli_credentials *creds,
 					int max_protocol,
 					const struct sockaddr_storage *dest_ss,
 					int port,
@@ -120,12 +120,12 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 	NTSTATUS status;
 	int flags = 0;
 	enum protocol_types protocol = PROTOCOL_NONE;
-	int signing_state = get_cmdline_auth_info_signing_state(auth_info);
-	struct cli_credentials *creds = NULL;
-	bool force_encrypt =
-		get_cmdline_auth_info_smb_encrypt(auth_info);
+	enum smb_signing_setting signing_state =
+		cli_credentials_get_smb_signing(creds);
+	enum smb_encryption_setting encryption_state =
+		cli_credentials_get_smb_encryption(creds);
 
-	if (force_encrypt) {
+	if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
 		signing_state = SMB_SIGNING_REQUIRED;
 	}
 
@@ -192,13 +192,12 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 		smb2cli_conn_set_max_credits(c->conn, DEFAULT_SMB2_MAX_CREDITS);
 	}
 
-	creds = get_cmdline_auth_info_creds(auth_info);
-
 	status = cli_session_setup_creds(c, creds);
 	if (!NT_STATUS_IS_OK(status)) {
 		/* If a password was not supplied then
 		 * try again with a null username. */
-		if (force_encrypt || smbXcli_conn_signing_mandatory(c->conn) ||
+		if (encryption_state == SMB_ENCRYPTION_REQUIRED ||
+			smbXcli_conn_signing_mandatory(c->conn) ||
 			cli_credentials_authentication_requested(creds) ||
 			cli_credentials_is_anonymous(creds) ||
 			!NT_STATUS_IS_OK(status = cli_session_setup_anon(c)))
@@ -233,7 +232,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 				creds)) {
 		cli_shutdown(c);
 		return do_connect(ctx, newserver,
-				newshare, auth_info,
+				newshare, creds,
 				max_protocol,
 				NULL, port, name_type, pcli);
 	}
@@ -247,13 +246,19 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 		return status;
 	}
 
-	if (force_encrypt) {
+	if (encryption_state >= SMB_ENCRYPTION_DESIRED) {
 		status = cli_cm_force_encryption_creds(c,
 						       creds,
 						       sharename);
 		if (!NT_STATUS_IS_OK(status)) {
-			cli_shutdown(c);
-			return status;
+			switch (encryption_state) {
+			case SMB_ENCRYPTION_DESIRED:
+				break;
+			case SMB_ENCRYPTION_REQUIRED:
+			default:
+				cli_shutdown(c);
+				return status;
+			}
 		}
 	}
 
@@ -295,10 +300,11 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 			       struct cli_state **pcli)
 {
 	struct cli_state *cli = NULL;
+	struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info);
 	NTSTATUS status;
 
 	status = do_connect(ctx, server, share,
-				auth_info,
+				creds,
 				max_protocol,
 				dest_ss, port, name_type, &cli);
 
-- 
2.29.2


From 5997be2fc0d9b25c7a81d1d21e3cc1cd3f55e66f Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 18 Aug 2020 17:18:16 +0200
Subject: [PATCH 067/104] s3:libsmb: Pass cli_credentials to cli_cm_connect()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit c8349111243fec81a2b95484e56a6d6bebaba80e)
---
 source3/libsmb/clidfs.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index d536e0597af..a2c6f5fe5ec 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -292,7 +292,7 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 			       struct cli_state *referring_cli,
 			       const char *server,
 			       const char *share,
-			       const struct user_auth_info *auth_info,
+			       struct cli_credentials *creds,
 			       int max_protocol,
 			       const struct sockaddr_storage *dest_ss,
 			       int port,
@@ -300,7 +300,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 			       struct cli_state **pcli)
 {
 	struct cli_state *cli = NULL;
-	struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info);
 	NTSTATUS status;
 
 	status = do_connect(ctx, server, share,
@@ -397,6 +396,7 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 {
 	/* Try to reuse an existing connection in this list. */
 	struct cli_state *c = cli_cm_find(referring_cli, server, share);
+	struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info);
 	NTSTATUS status;
 
 	if (c) {
@@ -417,7 +417,7 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				referring_cli,
 				server,
 				share,
-				auth_info,
+				creds,
 				max_protocol,
 				dest_ss,
 				port,
@@ -886,6 +886,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 	struct smbXcli_tcon *root_tcon = NULL;
 	struct smbXcli_tcon *target_tcon = NULL;
 	struct cli_dfs_path_split *dfs_refs = NULL;
+	struct cli_credentials *creds = get_cmdline_auth_info_creds(dfs_auth_info);
 
 	if ( !rootcli || !path || !targetcli ) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -1022,7 +1023,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 		status = cli_cm_connect(ctx, rootcli,
 				dfs_refs[count].server,
 				dfs_refs[count].share,
-				dfs_auth_info,
+				creds,
 				smbXcli_conn_protocol(rootcli->conn),
 				NULL, /* dest_ss */
 				0, /* port */
-- 
2.29.2


From 62109132050092a5b4ac81d80cb358e563da605c Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 18 Aug 2020 17:26:54 +0200
Subject: [PATCH 068/104] s3:libsmb: Pass cli_credentials to cli_cm_open()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit df1623abd7267916696e2e60c146ef8fa6c9dfc9)
---
 source3/client/client.c | 23 ++++++++++++++++++-----
 source3/lib/netapi/cm.c |  4 +++-
 source3/libsmb/clidfs.c | 25 ++++++++++++-------------
 source3/libsmb/proto.h  | 18 +++++++++---------
 4 files changed, 42 insertions(+), 28 deletions(-)

diff --git a/source3/client/client.c b/source3/client/client.c
index 3a610086511..c54b5065b44 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -5546,6 +5546,8 @@ static int process_command_string(const char *cmd_in)
 	TALLOC_CTX *ctx = talloc_tos();
 	char *cmd = talloc_strdup(ctx, cmd_in);
 	int rc = 0;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 
 	if (!cmd) {
 		return 1;
@@ -5557,7 +5559,8 @@ static int process_command_string(const char *cmd_in)
 
 		status = cli_cm_open(talloc_tos(), NULL,
 				     desthost,
-				     service, popt_get_cmdline_auth_info(),
+				     service,
+				     creds,
 				     max_protocol,
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type,
@@ -5998,10 +6001,13 @@ static int process(const char *base_directory)
 {
 	int rc = 0;
 	NTSTATUS status;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 
 	status = cli_cm_open(talloc_tos(), NULL,
 			     desthost,
-			     service, popt_get_cmdline_auth_info(),
+			     service,
+			     creds,
 			     max_protocol,
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
@@ -6036,10 +6042,13 @@ static int process(const char *base_directory)
 static int do_host_query(const char *query_host)
 {
 	NTSTATUS status;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 
 	status = cli_cm_open(talloc_tos(), NULL,
 			     query_host,
-			     "IPC$", popt_get_cmdline_auth_info(),
+			     "IPC$",
+			     creds,
 			     max_protocol,
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
@@ -6086,7 +6095,8 @@ static int do_host_query(const char *query_host)
 		d_printf("Reconnecting with SMB1 for workgroup listing.\n");
 		status = cli_cm_open(talloc_tos(), NULL,
 				     query_host,
-				     "IPC$", popt_get_cmdline_auth_info(),
+				     "IPC$",
+				     creds,
 				     max_proto,
 				     have_ip ? &dest_ss : NULL, NBT_SMB_PORT,
 				     name_type, &cli);
@@ -6113,6 +6123,8 @@ static int do_tar_op(const char *base_directory)
 {
 	struct tar *tar_ctx = tar_get_ctx();
 	int ret = 0;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 
 	/* do we already have a connection? */
 	if (!cli) {
@@ -6120,7 +6132,8 @@ static int do_tar_op(const char *base_directory)
 
 		status = cli_cm_open(talloc_tos(), NULL,
 				     desthost,
-				     service, popt_get_cmdline_auth_info(),
+				     service,
+				     creds,
 				     max_protocol,
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type, &cli);
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index 0fd31ef3d5a..943f7498e8c 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -71,6 +71,7 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
 	struct cli_state *cli_ipc = NULL;
 	struct client_ipc_connection *p;
 	NTSTATUS status;
+	struct cli_credentials *creds = NULL;
 
 	if (!ctx || !pp || !server_name) {
 		return WERR_INVALID_PARAMETER;
@@ -106,10 +107,11 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
 	if (ctx->use_ccache) {
 		set_cmdline_auth_info_use_ccache(auth_info, true);
 	}
+	creds = get_cmdline_auth_info_creds(auth_info);
 
 	status = cli_cm_open(ctx, NULL,
 			     server_name, "IPC$",
-			     auth_info,
+			     creds,
 			     lp_client_ipc_max_protocol(),
 			     NULL, 0, 0x20, &cli_ipc);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index a2c6f5fe5ec..ef75fb36a45 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -384,19 +384,18 @@ static struct cli_state *cli_cm_find(struct cli_state *cli,
 ****************************************************************************/
 
 NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
-				struct cli_state *referring_cli,
-				const char *server,
-				const char *share,
-				const struct user_auth_info *auth_info,
-				int max_protocol,
-				const struct sockaddr_storage *dest_ss,
-				int port,
-				int name_type,
-				struct cli_state **pcli)
+		     struct cli_state *referring_cli,
+		     const char *server,
+		     const char *share,
+		     struct cli_credentials *creds,
+		     int max_protocol,
+		     const struct sockaddr_storage *dest_ss,
+		     int port,
+		     int name_type,
+		     struct cli_state **pcli)
 {
 	/* Try to reuse an existing connection in this list. */
 	struct cli_state *c = cli_cm_find(referring_cli, server, share);
-	struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info);
 	NTSTATUS status;
 
 	if (c) {
@@ -404,11 +403,11 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 		return NT_STATUS_OK;
 	}
 
-	if (auth_info == NULL) {
+	if (creds == NULL) {
 		/* Can't do a new connection
 		 * without auth info. */
 		d_printf("cli_cm_open() Unable to open connection [\\%s\\%s] "
-			"without auth info\n",
+			"without client credentials\n",
 			server, share );
 		return NT_STATUS_INVALID_PARAMETER;
 	}
@@ -966,7 +965,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 			     rootcli,
 			     smbXcli_conn_remote_name(rootcli->conn),
 			     "IPC$",
-			     dfs_auth_info,
+			     creds,
 			     smbXcli_conn_protocol(rootcli->conn),
 			     NULL, /* dest_ss not needed, we reuse the transport */
 			     0,
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index f2b0a8c5ff8..0b8cf2a6036 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -124,15 +124,15 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx,
 /* The following definitions come from libsmb/clidfs.c  */
 
 NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
-				struct cli_state *referring_cli,
-				const char *server,
-				const char *share,
-				const struct user_auth_info *auth_info,
-				int max_protocol,
-				const struct sockaddr_storage *dest_ss,
-				int port,
-				int name_type,
-				struct cli_state **pcli);
+		     struct cli_state *referring_cli,
+		     const char *server,
+		     const char *share,
+		     struct cli_credentials *creds,
+		     int max_protocol,
+		     const struct sockaddr_storage *dest_ss,
+		     int port,
+		     int name_type,
+		     struct cli_state **pcli);
 void cli_cm_display(struct cli_state *c);
 struct client_dfs_referral;
 NTSTATUS cli_dfs_get_referral_ex(TALLOC_CTX *ctx,
-- 
2.29.2


From 9500031d977b874b32085df3ff7f5b0ae28514c6 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 18 Aug 2020 17:42:25 +0200
Subject: [PATCH 069/104] s3:libsmb: Pass cli_credentials to
 cli_resolve_path(), using helper variables.

Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 5245ab3c4dacc88d5cbe3bb1e3e339e4fb77a4db)
---
 source3/client/client.c       | 148 +++++++++++++++++++++++++++-------
 source3/libsmb/clidfs.c       |   5 +-
 source3/libsmb/libsmb_dir.c   |  43 ++++++++--
 source3/libsmb/libsmb_file.c  |  13 ++-
 source3/libsmb/libsmb_stat.c  |   6 +-
 source3/libsmb/libsmb_xattr.c |  13 ++-
 source3/libsmb/proto.h        |   2 +-
 source3/utils/smbcacls.c      |   5 +-
 8 files changed, 188 insertions(+), 47 deletions(-)

diff --git a/source3/client/client.c b/source3/client/client.c
index c54b5065b44..13e48f80a01 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -298,9 +298,14 @@ static int do_dskattr(void)
 	struct cli_state *targetcli = NULL;
 	char *targetpath = NULL;
 	TALLOC_CTX *ctx = talloc_tos();
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), cli,
+	status = cli_resolve_path(ctx,
+				  "",
+				  creds,
+				  cli,
 				  client_get_cur_dir(), &targetcli,
 				  &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -390,6 +395,8 @@ static int do_cd(const char *new_dir)
 	uint32_t attributes;
 	int ret = 1;
 	TALLOC_CTX *ctx = talloc_stackframe();
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	newdir = talloc_strdup(ctx, new_dir);
@@ -432,7 +439,8 @@ static int do_cd(const char *new_dir)
 	new_cd = client_clean_name(ctx, new_cd);
 	client_set_cur_dir(new_cd);
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, new_cd, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("cd %s: %s\n", new_cd, nt_errstr(status));
@@ -809,6 +817,8 @@ NTSTATUS do_list(const char *mask,
 	TALLOC_CTX *ctx = talloc_tos();
 	struct cli_state *targetcli = NULL;
 	char *targetpath = NULL;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS ret_status = NT_STATUS_OK;
 	NTSTATUS status = NT_STATUS_OK;
 
@@ -832,7 +842,7 @@ NTSTATUS do_list(const char *mask,
 		/* check for dfs */
 
 		status = cli_resolve_path(ctx, "",
-					  popt_get_cmdline_auth_info(),
+					  creds,
 					  cli, head, &targetcli, &targetpath);
 		if (!NT_STATUS_IS_OK(status)) {
 			d_printf("do_list: [%s] %s\n", head,
@@ -1042,6 +1052,8 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
 	struct cli_state *targetcli = NULL;
 	char *targetname = NULL;
 	char *lname = NULL;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	lname = talloc_strdup(ctx, lname_in);
@@ -1056,7 +1068,8 @@ static int do_get(const char *rname, const char *lname_in, bool reget)
 		}
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, rname, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Failed to open %s: %s\n", rname, nt_errstr(status));
@@ -1413,9 +1426,12 @@ static bool do_mkdir(const char *name)
 	TALLOC_CTX *ctx = talloc_tos();
 	struct cli_state *targetcli;
 	char *targetname = NULL;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, name, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("mkdir %s: %s\n", name, nt_errstr(status));
@@ -1474,6 +1490,8 @@ static int cmd_mkdir(void)
 	TALLOC_CTX *ctx = talloc_tos();
 	char *mask = NULL;
 	char *buf = NULL;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	mask = talloc_strdup(ctx, client_get_cur_dir());
@@ -1510,7 +1528,8 @@ static int cmd_mkdir(void)
 		}
 
 		status = cli_resolve_path(ctx, "",
-				popt_get_cmdline_auth_info(), cli, mask,
+					  creds,
+					  cli, mask,
 				&targetcli, &targetname);
 		if (!NT_STATUS_IS_OK(status)) {
 			return 1;
@@ -1824,9 +1843,12 @@ static int do_put(const char *rname, const char *lname, bool reput)
 	struct cli_state *targetcli;
 	char *targetname = NULL;
 	struct push_state state;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, rname, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Failed to open %s: %s\n", rname, nt_errstr(status));
@@ -2601,6 +2623,8 @@ static int cmd_wdel(void)
 	uint32_t attribute;
 	struct cli_state *targetcli;
 	char *targetname = NULL;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2626,7 +2650,8 @@ static int cmd_wdel(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("cmd_wdel %s: %s\n", mask, nt_errstr(status));
@@ -2652,6 +2677,8 @@ static int cmd_open(void)
 	char *targetname = NULL;
 	struct cli_state *targetcli;
 	uint16_t fnum = (uint16_t)-1;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2671,7 +2698,8 @@ static int cmd_open(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("open %s: %s\n", mask, nt_errstr(status));
@@ -2773,6 +2801,8 @@ static int cmd_posix_open(void)
 	struct cli_state *targetcli;
 	mode_t mode;
 	uint16_t fnum;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2797,7 +2827,8 @@ static int cmd_posix_open(void)
 	}
 	mode = (mode_t)strtol(buf, (char **)NULL, 8);
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("posix_open %s: %s\n", mask, nt_errstr(status));
@@ -2832,6 +2863,8 @@ static int cmd_posix_mkdir(void)
 	char *targetname = NULL;
 	struct cli_state *targetcli;
 	mode_t mode;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2856,7 +2889,8 @@ static int cmd_posix_mkdir(void)
 	}
 	mode = (mode_t)strtol(buf, (char **)NULL, 8);
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("posix_mkdir %s: %s\n", mask, nt_errstr(status));
@@ -2880,6 +2914,8 @@ static int cmd_posix_unlink(void)
 	char *buf = NULL;
 	char *targetname = NULL;
 	struct cli_state *targetcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2898,7 +2934,8 @@ static int cmd_posix_unlink(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("posix_unlink %s: %s\n", mask, nt_errstr(status));
@@ -2923,6 +2960,8 @@ static int cmd_posix_rmdir(void)
 	char *buf = NULL;
 	char *targetname = NULL;
 	struct cli_state *targetcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -2941,7 +2980,8 @@ static int cmd_posix_rmdir(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("posix_rmdir %s: %s\n", mask, nt_errstr(status));
@@ -3230,6 +3270,8 @@ static int cmd_rmdir(void)
 	char *buf = NULL;
 	char *targetname = NULL;
 	struct cli_state *targetcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -3248,7 +3290,8 @@ static int cmd_rmdir(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, mask, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("rmdir %s: %s\n", mask, nt_errstr(status));
@@ -3277,6 +3320,8 @@ static int cmd_link(void)
 	char *buf2 = NULL;
 	char *targetname = NULL;
 	struct cli_state *targetcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) ||
@@ -3307,7 +3352,8 @@ static int cmd_link(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, oldname, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("link %s: %s\n", oldname, nt_errstr(status));
@@ -3340,6 +3386,8 @@ static int cmd_readlink(void)
 	char *targetname = NULL;
 	char *linkname = NULL;
 	struct cli_state *targetcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) {
@@ -3358,7 +3406,8 @@ static int cmd_readlink(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, name, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("readlink %s: %s\n", name, nt_errstr(status));
@@ -3397,6 +3446,8 @@ static int cmd_symlink(void)
 	char *buf = NULL;
 	char *buf2 = NULL;
 	struct cli_state *newcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) ||
@@ -3419,7 +3470,8 @@ static int cmd_symlink(void)
 		}
 		/* New name must be present in share namespace. */
 		status = cli_resolve_path(ctx, "",
-				popt_get_cmdline_auth_info(), cli, newname,
+					  creds,
+					  cli, newname,
 				&newcli, &newname);
 		if (!NT_STATUS_IS_OK(status)) {
 			d_printf("link %s: %s\n", newname,
@@ -3455,6 +3507,8 @@ static int cmd_chmod(void)
 	char *targetname = NULL;
 	struct cli_state *targetcli;
 	mode_t mode;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) ||
@@ -3476,7 +3530,8 @@ static int cmd_chmod(void)
 
 	mode = (mode_t)strtol(buf, NULL, 8);
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("chmod %s: %s\n", src, nt_errstr(status));
@@ -3620,6 +3675,8 @@ static int cmd_getfacl(void)
 	size_t num_dir_acls = 0;
 	size_t expected_buflen;
 	uint16_t i;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
@@ -3638,7 +3695,8 @@ static int cmd_getfacl(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("stat %s: %s\n", src, nt_errstr(status));
@@ -3803,6 +3861,8 @@ static int cmd_geteas(void)
 	NTSTATUS status;
 	size_t i, num_eas;
 	struct ea_struct *eas;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
 		d_printf("geteas filename\n");
@@ -3820,7 +3880,8 @@ static int cmd_geteas(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("stat %s: %s\n", src, nt_errstr(status));
@@ -3859,6 +3920,8 @@ static int cmd_setea(void)
 	char *eavalue = NULL;
 	char *targetname = NULL;
 	struct cli_state *targetcli;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr, &name, NULL)
@@ -3881,7 +3944,8 @@ static int cmd_setea(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("stat %s: %s\n", src, nt_errstr(status));
@@ -3913,6 +3977,8 @@ static int cmd_stat(void)
 	SMB_STRUCT_STAT sbuf;
 	struct tm *lt;
 	time_t tmp_time;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) {
@@ -3931,7 +3997,8 @@ static int cmd_stat(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("stat %s: %s\n", src, nt_errstr(status));
@@ -4020,6 +4087,8 @@ static int cmd_chown(void)
 	char *buf, *buf2, *buf3;
 	struct cli_state *targetcli;
 	char *targetname = NULL;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) ||
@@ -4043,7 +4112,8 @@ static int cmd_chown(void)
 	if (src == NULL) {
 		return 1;
 	}
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("chown %s: %s\n", src, nt_errstr(status));
@@ -4077,6 +4147,8 @@ static int cmd_rename(void)
 	struct cli_state *targetcli;
 	char *targetsrc;
 	char *targetdest;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 	bool replace = false;
 
@@ -4115,14 +4187,16 @@ static int cmd_rename(void)
 		replace = true;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetsrc);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("rename %s: %s\n", src, nt_errstr(status));
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, dest, &targetcli, &targetdest);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("rename %s: %s\n", dest, nt_errstr(status));
@@ -4179,6 +4253,8 @@ static int cmd_scopy(void)
 	off_t written = 0;
 	struct scopy_timing st;
 	int rc = 0;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) ||
@@ -4211,14 +4287,16 @@ static int cmd_scopy(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, src, &targetcli, &targetsrc);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("scopy %s: %s\n", src, nt_errstr(status));
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 			cli, dest, &targetcli, &targetdest);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("scopy %s: %s\n", dest, nt_errstr(status));
@@ -4317,6 +4395,8 @@ static int cmd_hardlink(void)
 	char *buf, *buf2;
 	struct cli_state *targetcli;
 	char *targetname;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
         NTSTATUS status;
 
 	if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) ||
@@ -4349,7 +4429,8 @@ static int cmd_hardlink(void)
 		return 1;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, src, &targetcli, &targetname);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("hardlink %s: %s\n", src, nt_errstr(status));
@@ -5023,9 +5104,13 @@ static int cmd_show_connect( void )
 	TALLOC_CTX *ctx = talloc_tos();
 	struct cli_state *targetcli;
 	char *targetpath;
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), cli,
+	status = cli_resolve_path(ctx, "",
+				  creds,
+				  cli,
 				  client_get_cur_dir(), &targetcli,
 				  &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -5685,6 +5770,8 @@ static char **remote_completion(const char *text, int len)
 	struct cli_state *targetcli = NULL;
 	int i;
 	struct completion_remote info = { NULL, NULL, 1, 0, NULL, 0 };
+	struct cli_credentials *creds =
+		get_cmdline_auth_info_creds(popt_get_cmdline_auth_info());
 	NTSTATUS status;
 
 	/* can't have non-static initialisation on Sun CC, so do it
@@ -5745,7 +5832,8 @@ static char **remote_completion(const char *text, int len)
 		goto cleanup;
 	}
 
-	status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(),
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				cli, dirmask, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto cleanup;
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index ef75fb36a45..e6695159a96 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -859,7 +859,7 @@ struct cli_dfs_path_split {
 
 NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 			  const char *mountpt,
-			  const struct user_auth_info *dfs_auth_info,
+			  struct cli_credentials *creds,
 			  struct cli_state *rootcli,
 			  const char *path,
 			  struct cli_state **targetcli,
@@ -885,7 +885,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 	struct smbXcli_tcon *root_tcon = NULL;
 	struct smbXcli_tcon *target_tcon = NULL;
 	struct cli_dfs_path_split *dfs_refs = NULL;
-	struct cli_credentials *creds = get_cmdline_auth_info_creds(dfs_auth_info);
 
 	if ( !rootcli || !path || !targetcli ) {
 		return NT_STATUS_INVALID_PARAMETER;
@@ -1130,7 +1129,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 	if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) {
 		status = cli_resolve_path(ctx,
 					  newmount,
-					  dfs_auth_info,
+					  creds,
 					  *targetcli,
 					  *pp_targetpath,
 					  &newcli,
diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c
index 12abb734c2d..0326f27125b 100644
--- a/source3/libsmb/libsmb_dir.c
+++ b/source3/libsmb/libsmb_dir.c
@@ -911,6 +911,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
                          */
 			char *targetpath;
 			struct cli_state *targetcli;
+			struct cli_credentials *creds = NULL;
 			NTSTATUS status;
 
 			/* We connect to the server and list the directory */
@@ -943,8 +944,12 @@ SMBC_opendir_ctx(SMBCCTX *context,
 				return NULL;
 			}
 
+			creds = get_cmdline_auth_info_creds(
+					context->internal->auth_info);
+
 			status = cli_resolve_path(
-				frame, "", context->internal->auth_info,
+				frame, "",
+				creds,
 				srv->cli, path, &targetcli, &targetpath);
 			if (!NT_STATUS_IS_OK(status)) {
 				d_printf("Could not resolve %s\n", path);
@@ -1543,6 +1548,7 @@ SMBC_mkdir_ctx(SMBCCTX *context,
 	char *targetpath = NULL;
 	uint16_t port = 0;
 	struct cli_state *targetcli = NULL;
+	struct cli_credentials *creds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS status;
 
@@ -1595,8 +1601,11 @@ SMBC_mkdir_ctx(SMBCCTX *context,
 
 	}
 
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info);
+
 	/*d_printf(">>>mkdir: resolving %s\n", path);*/
-	status = cli_resolve_path(frame, "", context->internal->auth_info,
+	status = cli_resolve_path(frame, "",
+				  creds,
 				  srv->cli, path, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not resolve %s\n", path);
@@ -1654,6 +1663,7 @@ SMBC_rmdir_ctx(SMBCCTX *context,
         char *targetpath = NULL;
 	uint16_t port = 0;
 	struct cli_state *targetcli = NULL;
+	struct cli_credentials *creds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS status;
 
@@ -1706,8 +1716,11 @@ SMBC_rmdir_ctx(SMBCCTX *context,
 
 	}
 
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info),
+
 	/*d_printf(">>>rmdir: resolving %s\n", path);*/
-	status = cli_resolve_path(frame, "", context->internal->auth_info,
+	status = cli_resolve_path(frame, "",
+				  creds,
 				  srv->cli, path, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not resolve %s\n", path);
@@ -1959,6 +1972,7 @@ SMBC_chmod_ctx(SMBCCTX *context,
 	char *path = NULL;
 	uint32_t attr;
 	uint16_t port = 0;
+	struct cli_credentials *creds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
         NTSTATUS status;
 
@@ -2010,8 +2024,11 @@ SMBC_chmod_ctx(SMBCCTX *context,
 		return -1;  /* errno set by SMBC_server */
 	}
 	
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info);
+
 	/*d_printf(">>>unlink: resolving %s\n", path);*/
-	status = cli_resolve_path(frame, "", context->internal->auth_info,
+	status = cli_resolve_path(frame, "",
+				  creds,
 				  srv->cli, path, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not resolve %s\n", path);
@@ -2152,6 +2169,7 @@ SMBC_unlink_ctx(SMBCCTX *context,
 	uint16_t port = 0;
 	struct cli_state *targetcli = NULL;
 	SMBCSRV *srv = NULL;
+	struct cli_credentials *creds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
         NTSTATUS status;
 
@@ -2204,8 +2222,11 @@ SMBC_unlink_ctx(SMBCCTX *context,
 
 	}
 
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info);
+
 	/*d_printf(">>>unlink: resolving %s\n", path);*/
-	status = cli_resolve_path(frame, "", context->internal->auth_info,
+	status = cli_resolve_path(frame, "",
+				  creds,
 				  srv->cli, path, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not resolve %s\n", path);
@@ -2282,6 +2303,8 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
 	SMBCSRV *srv = NULL;
 	uint16_t port1 = 0;
 	uint16_t port2 = 0;
+	struct cli_credentials *ocreds = NULL;
+	struct cli_credentials *ncreds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
         NTSTATUS status;
 
@@ -2375,7 +2398,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
 				    	   password1);
 
 	/*d_printf(">>>rename: resolving %s\n", path1);*/
-	status = cli_resolve_path(frame, "", ocontext->internal->auth_info,
+	ocreds = get_cmdline_auth_info_creds(ocontext->internal->auth_info);
+
+	status = cli_resolve_path(frame, "",
+				  ocreds,
 				  srv->cli, path1, &targetcli1, &targetpath1);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not resolve %s\n", path1);
@@ -2392,7 +2418,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext,
 	
 	/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
 	/*d_printf(">>>rename: resolving %s\n", path2);*/
-	status = cli_resolve_path(frame, "", ncontext->internal->auth_info,
+	ncreds = get_cmdline_auth_info_creds(ncontext->internal->auth_info);
+
+	status = cli_resolve_path(frame, "",
+				  ncreds,
 				  srv->cli, path2, &targetcli2, &targetpath2);
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("Could not resolve %s\n", path2);
diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c
index 0791df36690..a44925e0e0e 100644
--- a/source3/libsmb/libsmb_file.c
+++ b/source3/libsmb/libsmb_file.c
@@ -103,6 +103,8 @@ SMBC_open_ctx(SMBCCTX *context,
 	if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') {
 		status = NT_STATUS_OBJECT_PATH_INVALID;
 	} else {
+		struct cli_credentials *creds = NULL;
+
 		file = SMB_MALLOC_P(SMBCFILE);
 		if (!file) {
 			errno = ENOMEM;
@@ -112,9 +114,12 @@ SMBC_open_ctx(SMBCCTX *context,
 
 		ZERO_STRUCTP(file);
 
+		creds = get_cmdline_auth_info_creds(
+						context->internal->auth_info);
 		/*d_printf(">>>open: resolving %s\n", path);*/
 		status = cli_resolve_path(
-			frame, "", context->internal->auth_info,
+			frame, "",
+			creds,
 			srv->cli, path, &targetcli, &targetpath);
 		if (!NT_STATUS_IS_OK(status)) {
 			d_printf("Could not resolve %s\n", path);
@@ -461,6 +466,7 @@ SMBC_getatr(SMBCCTX * context,
 	struct timespec change_time_ts = {0};
 	time_t write_time = 0;
 	SMB_INO_T ino = 0;
+	struct cli_credentials *creds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS status;
 
@@ -490,7 +496,10 @@ SMBC_getatr(SMBCCTX * context,
 	}
 	DEBUG(4,("SMBC_getatr: sending qpathinfo\n"));
 
-	status = cli_resolve_path(frame, "", context->internal->auth_info,
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info);
+
+	status = cli_resolve_path(frame, "",
+				  creds,
 				  srv->cli, fixedpath,
 				  &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c
index 790934bd565..1260928d0ff 100644
--- a/source3/libsmb/libsmb_stat.c
+++ b/source3/libsmb/libsmb_stat.c
@@ -242,6 +242,7 @@ SMBC_fstat_ctx(SMBCCTX *context,
 	struct cli_state *targetcli = NULL;
 	SMB_INO_T ino = 0;
 	uint16_t port = 0;
+	struct cli_credentials *creds = NULL;
 	TALLOC_CTX *frame = talloc_stackframe();
 	NTSTATUS status;
 
@@ -279,8 +280,11 @@ SMBC_fstat_ctx(SMBCCTX *context,
                 return -1;
         }
 
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info);
+
 	/*d_printf(">>>fstat: resolving %s\n", path);*/
-	status = cli_resolve_path(frame, "", context->internal->auth_info,
+	status = cli_resolve_path(frame, "",
+				  creds,
 				  file->srv->cli, path,
 				  &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c
index d1b6548eb90..8b74d0a39e3 100644
--- a/source3/libsmb/libsmb_xattr.c
+++ b/source3/libsmb/libsmb_xattr.c
@@ -860,13 +860,18 @@ cacl_get(SMBCCTX *context,
         if (ipc_cli && (all || some_nt || all_nt_acls)) {
 		char *targetpath = NULL;
 	        struct cli_state *targetcli = NULL;
+		struct cli_credentials *creds = NULL;
 		NTSTATUS status;
 
                 /* Point to the portion after "system.nt_sec_desc." */
                 name += 19;     /* if (all) this will be invalid but unused */
 
+		creds = get_cmdline_auth_info_creds(
+				context->internal->auth_info);
+
 		status = cli_resolve_path(
-			ctx, "", context->internal->auth_info,
+			ctx, "",
+			creds,
 			cli, filename, &targetcli, &targetpath);
 		if (!NT_STATUS_IS_OK(status)) {
 			DEBUG(5, ("cacl_get Could not resolve %s\n",
@@ -1511,6 +1516,7 @@ cacl_set(SMBCCTX *context,
         bool numeric = True;
 	char *targetpath = NULL;
 	struct cli_state *targetcli = NULL;
+	struct cli_credentials *creds = NULL;
 	NTSTATUS status;
 
         /* the_acl will be null for REMOVE_ALL operations */
@@ -1540,7 +1546,10 @@ cacl_set(SMBCCTX *context,
 		return -1;
 	}
 
-	status = cli_resolve_path(ctx, "", context->internal->auth_info,
+	creds = get_cmdline_auth_info_creds(context->internal->auth_info);
+
+	status = cli_resolve_path(ctx, "",
+				  creds,
 				  cli, filename, &targetcli, &targetpath);
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(5,("cacl_set: Could not resolve %s\n", filename));
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 0b8cf2a6036..517738dbcd7 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -150,7 +150,7 @@ NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx,
 			size_t *consumed);
 NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 			  const char *mountpt,
-			  const struct user_auth_info *dfs_auth_info,
+			  struct cli_credentials *creds,
 			  struct cli_state *rootcli,
 			  const char *path,
 			  struct cli_state **targetcli,
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 8fd9fcc5780..4989ec633c3 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -806,6 +806,7 @@ int main(int argc, char *argv[])
 	   than going via LSA calls to resolve them */
 	int numeric = 0;
 	struct cli_state *targetcli = NULL;
+	struct cli_credentials *creds = NULL;
 	char *targetfile = NULL;
 	NTSTATUS status;
 
@@ -1069,9 +1070,11 @@ int main(int argc, char *argv[])
 		}
 	}
 
+	creds = get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()),
+
 	status = cli_resolve_path(frame,
 				  "",
-				  popt_get_cmdline_auth_info(),
+				  creds,
 				  cli,
 				  filename,
 				  &targetcli,
-- 
2.29.2


From e3ce5ba85266a08bd201c851e8fd59b71322d03e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 16:40:49 +0200
Subject: [PATCH 070/104] s3:client: Remove global max_protocol

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit d07f28645f37c1f976017d5b89864791a18d1943)
---
 source3/client/client.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/source3/client/client.c b/source3/client/client.c
index 13e48f80a01..902cdec8b64 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -61,7 +61,6 @@ static int io_bufsize = 0; /* we use the default size */
 static int io_timeout = (CLIENT_TIMEOUT/1000); /* Per operation timeout (in seconds). */
 
 static int name_type = 0x20;
-static int max_protocol = -1;
 
 static int process_tok(char *tok);
 static int cmd_help(void);
@@ -5646,7 +5645,7 @@ static int process_command_string(const char *cmd_in)
 				     desthost,
 				     service,
 				     creds,
-				     max_protocol,
+				     lp_client_max_protocol(),
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type,
 				     &cli);
@@ -6096,7 +6095,7 @@ static int process(const char *base_directory)
 			     desthost,
 			     service,
 			     creds,
-			     max_protocol,
+			     lp_client_max_protocol(),
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -6137,7 +6136,7 @@ static int do_host_query(const char *query_host)
 			     query_host,
 			     "IPC$",
 			     creds,
-			     max_protocol,
+			     lp_client_max_protocol(),
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -6172,7 +6171,7 @@ static int do_host_query(const char *query_host)
 	if (port != NBT_SMB_PORT ||
 	    smbXcli_conn_protocol(cli->conn) > PROTOCOL_NT1)
 	{
-		int max_proto = MIN(max_protocol, PROTOCOL_NT1);
+		int max_proto = MIN(lp_client_max_protocol(), PROTOCOL_NT1);
 
 		/*
 		 * Workgroups simply don't make sense over anything
@@ -6222,7 +6221,7 @@ static int do_tar_op(const char *base_directory)
 				     desthost,
 				     service,
 				     creds,
-				     max_protocol,
+				     lp_client_max_protocol(),
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type, &cli);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -6629,8 +6628,6 @@ int main(int argc,char *argv[])
 	/* Ensure we have a password (or equivalent). */
 	popt_common_credentials_post();
 
-	max_protocol = lp_client_max_protocol();
-
 	if (tar_to_process(tar_ctx)) {
 		if (cmdstr)
 			process_command_string(cmdstr);
-- 
2.29.2


From 156a763a247480a88ab79f8822a2f34670a0c63b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 16:43:46 +0200
Subject: [PATCH 071/104] s3:libsmb: Remove max_protocol from cli_cm_open()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 4aac9daf095e7c2de6a27697a13385ee87a4b634)
---
 source3/client/client.c | 7 -------
 source3/lib/netapi/cm.c | 1 -
 source3/libsmb/clidfs.c | 4 +---
 source3/libsmb/proto.h  | 1 -
 4 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/source3/client/client.c b/source3/client/client.c
index 902cdec8b64..82764c5ca16 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -5645,7 +5645,6 @@ static int process_command_string(const char *cmd_in)
 				     desthost,
 				     service,
 				     creds,
-				     lp_client_max_protocol(),
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type,
 				     &cli);
@@ -6095,7 +6094,6 @@ static int process(const char *base_directory)
 			     desthost,
 			     service,
 			     creds,
-			     lp_client_max_protocol(),
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -6136,7 +6134,6 @@ static int do_host_query(const char *query_host)
 			     query_host,
 			     "IPC$",
 			     creds,
-			     lp_client_max_protocol(),
 			     have_ip ? &dest_ss : NULL, port,
 			     name_type, &cli);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -6171,8 +6168,6 @@ static int do_host_query(const char *query_host)
 	if (port != NBT_SMB_PORT ||
 	    smbXcli_conn_protocol(cli->conn) > PROTOCOL_NT1)
 	{
-		int max_proto = MIN(lp_client_max_protocol(), PROTOCOL_NT1);
-
 		/*
 		 * Workgroups simply don't make sense over anything
 		 * else but port 139 and SMB1.
@@ -6184,7 +6179,6 @@ static int do_host_query(const char *query_host)
 				     query_host,
 				     "IPC$",
 				     creds,
-				     max_proto,
 				     have_ip ? &dest_ss : NULL, NBT_SMB_PORT,
 				     name_type, &cli);
 		if (!NT_STATUS_IS_OK(status)) {
@@ -6221,7 +6215,6 @@ static int do_tar_op(const char *base_directory)
 				     desthost,
 				     service,
 				     creds,
-				     lp_client_max_protocol(),
 				     have_ip ? &dest_ss : NULL, port,
 				     name_type, &cli);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c
index 943f7498e8c..3f4e188b396 100644
--- a/source3/lib/netapi/cm.c
+++ b/source3/lib/netapi/cm.c
@@ -112,7 +112,6 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx,
 	status = cli_cm_open(ctx, NULL,
 			     server_name, "IPC$",
 			     creds,
-			     lp_client_ipc_max_protocol(),
 			     NULL, 0, 0x20, &cli_ipc);
 	if (!NT_STATUS_IS_OK(status)) {
 		cli_ipc = NULL;
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index e6695159a96..fb1a0c72e6d 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -388,7 +388,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 		     const char *server,
 		     const char *share,
 		     struct cli_credentials *creds,
-		     int max_protocol,
 		     const struct sockaddr_storage *dest_ss,
 		     int port,
 		     int name_type,
@@ -417,7 +416,7 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				server,
 				share,
 				creds,
-				max_protocol,
+				lp_client_max_protocol(),
 				dest_ss,
 				port,
 				name_type,
@@ -965,7 +964,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 			     smbXcli_conn_remote_name(rootcli->conn),
 			     "IPC$",
 			     creds,
-			     smbXcli_conn_protocol(rootcli->conn),
 			     NULL, /* dest_ss not needed, we reuse the transport */
 			     0,
 			     0x20,
diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h
index 517738dbcd7..8aaaff2cb1e 100644
--- a/source3/libsmb/proto.h
+++ b/source3/libsmb/proto.h
@@ -128,7 +128,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 		     const char *server,
 		     const char *share,
 		     struct cli_credentials *creds,
-		     int max_protocol,
 		     const struct sockaddr_storage *dest_ss,
 		     int port,
 		     int name_type,
-- 
2.29.2


From 2ad30b082df42e010ca88e7a84471629476e00b9 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 16:45:12 +0200
Subject: [PATCH 072/104] s3:libcmb: Remove max_protocol from cli_cm_connect()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 2159582610ecc932047b85a77ec321b3d3ac806f)
---
 source3/libsmb/clidfs.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index fb1a0c72e6d..023dd4d2757 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -293,7 +293,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 			       const char *server,
 			       const char *share,
 			       struct cli_credentials *creds,
-			       int max_protocol,
 			       const struct sockaddr_storage *dest_ss,
 			       int port,
 			       int name_type,
@@ -304,7 +303,7 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 
 	status = do_connect(ctx, server, share,
 				creds,
-				max_protocol,
+				lp_client_max_protocol(),
 				dest_ss, port, name_type, &cli);
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -416,7 +415,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx,
 				server,
 				share,
 				creds,
-				lp_client_max_protocol(),
 				dest_ss,
 				port,
 				name_type,
@@ -1020,7 +1018,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx,
 				dfs_refs[count].server,
 				dfs_refs[count].share,
 				creds,
-				smbXcli_conn_protocol(rootcli->conn),
 				NULL, /* dest_ss */
 				0, /* port */
 				0x20,
-- 
2.29.2


From 4cc3243a8cf7c18129ad41ea52abc325aef55f06 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 27 Aug 2020 16:46:29 +0200
Subject: [PATCH 073/104] s3:libsmb: Remove max_protocol from clidfs
 do_connect()

The if check for max_protocol == 0 is part of lp_client_max_protocol().

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 50b59b4c28bc816094a4ca97f64450860e2495b2)
---
 source3/libsmb/clidfs.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 023dd4d2757..ee5becf76a6 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -107,7 +107,6 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 					const char *server,
 					const char *share,
 					struct cli_credentials *creds,
-					int max_protocol,
 					const struct sockaddr_storage *dest_ss,
 					int port,
 					int name_type,
@@ -167,14 +166,11 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 		return status;
 	}
 
-	if (max_protocol == 0) {
-		max_protocol = PROTOCOL_LATEST;
-	}
 	DEBUG(4,(" session request ok\n"));
 
 	status = smbXcli_negprot(c->conn, c->timeout,
 				 lp_client_min_protocol(),
-				 max_protocol);
+				 lp_client_max_protocol());
 
 	if (!NT_STATUS_IS_OK(status)) {
 		d_printf("protocol negotiation failed: %s\n",
@@ -233,7 +229,6 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx,
 		cli_shutdown(c);
 		return do_connect(ctx, newserver,
 				newshare, creds,
-				max_protocol,
 				NULL, port, name_type, pcli);
 	}
 
@@ -303,7 +298,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx,
 
 	status = do_connect(ctx, server, share,
 				creds,
-				lp_client_max_protocol(),
 				dest_ss, port, name_type, &cli);
 
 	if (!NT_STATUS_IS_OK(status)) {
-- 
2.29.2


From bfd80fa8f7a476b2fb37bd435697700ad032cc70 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 10 Aug 2020 15:47:35 +0200
Subject: [PATCH 074/104] s3:include: Move loadparm prototypes to own header
 file

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit d4d8218b9618dd289f54b41f13d7015f1b3994fd)
---
 source3/include/includes.h |   3 +
 source3/include/proto.h    | 167 -------------------------------
 source3/param/loadparm.h   | 200 +++++++++++++++++++++++++++++++++++++
 3 files changed, 203 insertions(+), 167 deletions(-)
 create mode 100644 source3/param/loadparm.h

diff --git a/source3/include/includes.h b/source3/include/includes.h
index 8fa65cc3122..c94f919ed59 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -293,6 +293,9 @@ typedef char fstring[FSTRING_LEN];
 #endif
 
 #include "lib/param/loadparm.h"
+#include "source3/param/loadparm.h"
+/* Automatically generated by generate_param.py. */
+#include "source3/param/param_proto.h"
 
 /* String routines */
 
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 12aa392abae..b9a6cb7f116 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -739,173 +739,6 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
 			 const char *dcname,
 			 bool force);
 
-/* The following definitions come from param/loadparm.c  */
-
-const struct loadparm_substitution *loadparm_s3_global_substitution(void);
-
-char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
-				 const struct loadparm_substitution *lp_sub,
-				 int snum,
-				 const char *type,
-				 const char *option,
-				 const char *def);
-
-#include "source3/param/param_proto.h"
-
-char *lp_servicename(TALLOC_CTX *ctx, const struct loadparm_substitution *, int);
-const char *lp_const_servicename(int);
-bool lp_autoloaded(int);
-const char *lp_dnsdomain(void);
-int lp_winbind_max_domain_connections(void);
-bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high);
-bool lp_idmap_default_range(uint32_t *low, uint32_t *high);
-const char *lp_idmap_backend(const char *domain_name);
-const char *lp_idmap_default_backend (void);
-int lp_security(void);
-int lp_client_max_protocol(void);
-int lp_client_ipc_min_protocol(void);
-int lp_client_ipc_max_protocol(void);
-int lp_client_ipc_signing(void);
-int lp_smb2_max_credits(void);
-int lp_cups_encrypt(void);
-bool lp_widelinks(int );
-int lp_rpc_low_port(void);
-int lp_rpc_high_port(void);
-bool lp_lanman_auth(void);
-enum samba_weak_crypto lp_weak_crypto(void);
-
-int lp_wi_scan_global_parametrics(
-	const char *regex, size_t max_matches,
-	bool (*cb)(const char *string, regmatch_t matches[],
-		   void *private_data),
-	void *private_data);
-
-const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def);
-struct loadparm_service;
-const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type,
-					 const char *option, const char *def);
-const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def);
-int lp_parm_int(int snum, const char *type, const char *option, int def);
-unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def);
-unsigned long long lp_parm_ulonglong(int snum, const char *type,
-				     const char *option,
-				     unsigned long long def);
-bool lp_parm_bool(int snum, const char *type, const char *option, bool def);
-struct enum_list;
-int lp_parm_enum(int snum, const char *type, const char *option,
-		 const struct enum_list *_enum, int def);
-char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src);
-bool lp_add_home(const char *pszHomename, int iDefaultService,
-		 const char *user, const char *pszHomedir);
-int lp_add_service(const char *pszService, int iDefaultService);
-bool lp_add_printer(const char *pszPrintername, int iDefaultService);
-bool lp_parameter_is_valid(const char *pszParmName);
-bool lp_parameter_is_global(const char *pszParmName);
-bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
-			       bool *inverse);
-bool lp_canonicalize_parameter_with_value(const char *parm_name,
-					  const char *val,
-					  const char **canon_parm,
-					  const char **canon_val);
-void show_parameter_list(void);
-bool lp_invert_boolean(const char *str, const char **inverse_str);
-bool lp_canonicalize_boolean(const char *str, const char**canon_str);
-bool process_registry_service(const char *service_name);
-bool process_registry_shares(void);
-bool lp_config_backend_is_registry(void);
-bool lp_config_backend_is_file(void);
-bool lp_file_list_changed(void);
-const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx);
-const char *lp_ldap_user_suffix(TALLOC_CTX *ctx);
-const char *lp_ldap_group_suffix(TALLOC_CTX *ctx);
-const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx);
-struct parm_struct;
-/* Return a pointer to a service by name.  */
-struct loadparm_service *lp_service(const char *pszServiceName);
-struct loadparm_service *lp_servicebynum(int snum);
-struct loadparm_service *lp_default_loadparm_service(void);
-void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm);
-void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm);
-bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue);
-bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue);
-bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal);
-bool lp_snum_ok(int iService);
-void lp_add_one_printer(const char *name, const char *comment,
-			const char *location, void *pdata);
-bool lp_loaded(void);
-void lp_killunused(struct smbd_server_connection *sconn,
-		   bool (*snumused) (struct smbd_server_connection *, int));
-void lp_kill_all_services(void);
-void lp_killservice(int iServiceIn);
-const char* server_role_str(uint32_t role);
-enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
-			SMB_STRUCT_STAT *psbuf,
-			const char *servicename,
-			int snum,
-			char **lines,
-			int numlines,
-			char **pp_sharepath,
-			char **pp_comment,
-			char **pp_cp_share_name,
-			struct security_descriptor **ppsd,
-			bool *pallow_guest);
-int load_usershare_service(const char *servicename);
-int load_usershare_shares(struct smbd_server_connection *sconn,
-			  bool (*snumused) (struct smbd_server_connection *, int));
-void gfree_loadparm(void);
-bool lp_load_initial_only(const char *pszFname);
-bool lp_load_global(const char *file_name);
-bool lp_load_with_shares(const char *file_name);
-bool lp_load_client(const char *file_name);
-bool lp_load_global_no_reinit(const char *file_name);
-bool lp_load_no_reinit(const char *file_name);
-bool lp_load_client_no_reinit(const char *file_name);
-bool lp_load_with_registry_shares(const char *pszFname);
-int lp_numservices(void);
-void lp_dump(FILE *f, bool show_defaults, int maxtoprint);
-void lp_dump_one(FILE * f, bool show_defaults, int snum);
-int lp_servicenumber(const char *pszServiceName);
-const char *volume_label(TALLOC_CTX *ctx, int snum);
-bool lp_domain_master(void);
-bool lp_preferred_master(void);
-void lp_remove_service(int snum);
-void lp_copy_service(int snum, const char *new_name);
-int lp_default_server_announce(void);
-const char *lp_printername(TALLOC_CTX *ctx,
-			   const struct loadparm_substitution *lp_sub,
-			   int snum);
-void lp_set_logfile(const char *name);
-int lp_maxprintjobs(int snum);
-const char *lp_printcapname(void);
-bool lp_disable_spoolss( void );
-void lp_set_spoolss_state( uint32_t state );
-uint32_t lp_get_spoolss_state( void );
-struct smb_signing_state;
-void set_use_sendfile(int snum, bool val);
-void lp_set_mangling_method(const char *new_method);
-bool lp_posix_pathnames(void);
-void lp_set_posix_pathnames(void);
-enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp);
-void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val);
-int lp_min_receive_file_size(void);
-void widelinks_warning(int snum);
-const char *lp_ncalrpc_dir(void);
-void _lp_set_server_role(int server_role);
-
-/* The following definitions come from param/loadparm_ctx.c  */
-
-const struct loadparm_s3_helpers *loadparm_s3_helpers(void);
-
-/* The following definitions come from param/loadparm_server_role.c  */
-
-int lp_server_role(void);
-void set_server_role(void);
-
-/* The following definitions come from param/util.c  */
-
-uint32_t get_int_param( const char* param );
-char* get_string_param( const char* param );
-
 /* The following definitions come from lib/server_contexts.c  */
 struct tevent_context *global_event_context(void);
 void global_event_context_free(void);
diff --git a/source3/param/loadparm.h b/source3/param/loadparm.h
new file mode 100644
index 00000000000..7686877ccf1
--- /dev/null
+++ b/source3/param/loadparm.h
@@ -0,0 +1,200 @@
+/*
+ *
+ * Unix SMB/CIFS implementation.
+ *
+ * Type definitions for loadparm
+ *
+ * Copyright (c) 2020      Andreas Schneider <asn@samba.org>
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _S3_LOADPARM_H
+#define _S3_LOADPARM_H
+
+#include <talloc.h>
+#include <regex.h>
+
+/* Forward declarations */
+typedef struct stat_ex SMB_STRUCT_STAT;
+typedef struct files_struct files_struct;
+struct smbd_server_connection;
+struct security_descriptor;
+
+/* The following definitions come from param/loadparm.c  */
+
+const struct loadparm_substitution *loadparm_s3_global_substitution(void);
+
+char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
+				 const struct loadparm_substitution *lp_sub,
+				 int snum,
+				 const char *type,
+				 const char *option,
+				 const char *def);
+
+char *lp_servicename(TALLOC_CTX *ctx, const struct loadparm_substitution *, int);
+const char *lp_const_servicename(int);
+bool lp_autoloaded(int);
+const char *lp_dnsdomain(void);
+int lp_winbind_max_domain_connections(void);
+bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high);
+bool lp_idmap_default_range(uint32_t *low, uint32_t *high);
+const char *lp_idmap_backend(const char *domain_name);
+const char *lp_idmap_default_backend (void);
+int lp_security(void);
+int lp_client_max_protocol(void);
+int lp_client_ipc_min_protocol(void);
+int lp_client_ipc_max_protocol(void);
+int lp_client_ipc_signing(void);
+int lp_smb2_max_credits(void);
+int lp_cups_encrypt(void);
+bool lp_widelinks(int );
+int lp_rpc_low_port(void);
+int lp_rpc_high_port(void);
+bool lp_lanman_auth(void);
+enum samba_weak_crypto lp_weak_crypto(void);
+
+int lp_wi_scan_global_parametrics(
+	const char *regex, size_t max_matches,
+	bool (*cb)(const char *string, regmatch_t matches[],
+		   void *private_data),
+	void *private_data);
+
+const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def);
+struct loadparm_service;
+const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type,
+					 const char *option, const char *def);
+const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def);
+int lp_parm_int(int snum, const char *type, const char *option, int def);
+unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def);
+unsigned long long lp_parm_ulonglong(int snum, const char *type,
+				     const char *option,
+				     unsigned long long def);
+bool lp_parm_bool(int snum, const char *type, const char *option, bool def);
+struct enum_list;
+int lp_parm_enum(int snum, const char *type, const char *option,
+		 const struct enum_list *_enum, int def);
+char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src);
+bool lp_add_home(const char *pszHomename, int iDefaultService,
+		 const char *user, const char *pszHomedir);
+int lp_add_service(const char *pszService, int iDefaultService);
+bool lp_add_printer(const char *pszPrintername, int iDefaultService);
+bool lp_parameter_is_valid(const char *pszParmName);
+bool lp_parameter_is_global(const char *pszParmName);
+bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
+			       bool *inverse);
+bool lp_canonicalize_parameter_with_value(const char *parm_name,
+					  const char *val,
+					  const char **canon_parm,
+					  const char **canon_val);
+void show_parameter_list(void);
+bool lp_invert_boolean(const char *str, const char **inverse_str);
+bool lp_canonicalize_boolean(const char *str, const char**canon_str);
+bool process_registry_service(const char *service_name);
+bool process_registry_shares(void);
+bool lp_config_backend_is_registry(void);
+bool lp_config_backend_is_file(void);
+bool lp_file_list_changed(void);
+const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx);
+const char *lp_ldap_user_suffix(TALLOC_CTX *ctx);
+const char *lp_ldap_group_suffix(TALLOC_CTX *ctx);
+const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx);
+struct parm_struct;
+/* Return a pointer to a service by name.  */
+struct loadparm_service *lp_service(const char *pszServiceName);
+struct loadparm_service *lp_servicebynum(int snum);
+struct loadparm_service *lp_default_loadparm_service(void);
+void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm);
+void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm);
+bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue);
+bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue);
+bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal);
+bool lp_snum_ok(int iService);
+void lp_add_one_printer(const char *name, const char *comment,
+			const char *location, void *pdata);
+bool lp_loaded(void);
+void lp_killunused(struct smbd_server_connection *sconn,
+		   bool (*snumused) (struct smbd_server_connection *, int));
+void lp_kill_all_services(void);
+void lp_killservice(int iServiceIn);
+const char* server_role_str(uint32_t role);
+enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
+			SMB_STRUCT_STAT *psbuf,
+			const char *servicename,
+			int snum,
+			char **lines,
+			int numlines,
+			char **pp_sharepath,
+			char **pp_comment,
+			char **pp_cp_share_name,
+			struct security_descriptor **ppsd,
+			bool *pallow_guest);
+int load_usershare_service(const char *servicename);
+int load_usershare_shares(struct smbd_server_connection *sconn,
+			  bool (*snumused) (struct smbd_server_connection *, int));
+void gfree_loadparm(void);
+bool lp_load_initial_only(const char *pszFname);
+bool lp_load_global(const char *file_name);
+bool lp_load_with_shares(const char *file_name);
+bool lp_load_client(const char *file_name);
+bool lp_load_global_no_reinit(const char *file_name);
+bool lp_load_no_reinit(const char *file_name);
+bool lp_load_client_no_reinit(const char *file_name);
+bool lp_load_with_registry_shares(const char *pszFname);
+int lp_numservices(void);
+void lp_dump(FILE *f, bool show_defaults, int maxtoprint);
+void lp_dump_one(FILE * f, bool show_defaults, int snum);
+int lp_servicenumber(const char *pszServiceName);
+const char *volume_label(TALLOC_CTX *ctx, int snum);
+bool lp_domain_master(void);
+bool lp_preferred_master(void);
+void lp_remove_service(int snum);
+void lp_copy_service(int snum, const char *new_name);
+int lp_default_server_announce(void);
+const char *lp_printername(TALLOC_CTX *ctx,
+			   const struct loadparm_substitution *lp_sub,
+			   int snum);
+void lp_set_logfile(const char *name);
+int lp_maxprintjobs(int snum);
+const char *lp_printcapname(void);
+bool lp_disable_spoolss( void );
+void lp_set_spoolss_state( uint32_t state );
+uint32_t lp_get_spoolss_state( void );
+struct smb_signing_state;
+void set_use_sendfile(int snum, bool val);
+void lp_set_mangling_method(const char *new_method);
+bool lp_posix_pathnames(void);
+void lp_set_posix_pathnames(void);
+enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp);
+void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val);
+int lp_min_receive_file_size(void);
+void widelinks_warning(int snum);
+const char *lp_ncalrpc_dir(void);
+void _lp_set_server_role(int server_role);
+uint32_t lp_get_async_dns_timeout(void);
+
+/* The following definitions come from param/loadparm_ctx.c  */
+
+const struct loadparm_s3_helpers *loadparm_s3_helpers(void);
+
+/* The following definitions come from param/loadparm_server_role.c  */
+
+int lp_server_role(void);
+void set_server_role(void);
+
+/* The following definitions come from param/util.c  */
+
+uint32_t get_int_param( const char* param );
+char *get_string_param( const char* param );
+
+#endif /* _S3_LOADPARM_H */
-- 
2.29.2


From ad73140f7e08472179ac7598cfea780a207f0570 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 11 Aug 2020 10:41:07 +0200
Subject: [PATCH 075/104] s3:lib: Move interface prototypes to own header file

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>

Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Fri Oct  9 20:36:13 UTC 2020 on sn-devel-184

(cherry picked from commit 925cc9aafbe17cb2cbd89f468fac70f96ae89475)
---
 source3/include/proto.h | 21 +------------------
 source3/lib/interface.h | 46 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 20 deletions(-)
 create mode 100644 source3/lib/interface.h

diff --git a/source3/include/proto.h b/source3/include/proto.h
index b9a6cb7f116..1bbd8e9d526 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -84,26 +84,7 @@ NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx,
 		       struct connection_struct *conn,
 		       struct files_struct **_fsp);
 
-/* The following definitions come from lib/interface.c  */
-
-bool ismyaddr(const struct sockaddr *ip);
-bool ismyip_v4(struct in_addr ip);
-bool is_local_net(const struct sockaddr *from);
-void setup_linklocal_scope_id(struct sockaddr *pss);
-bool is_local_net_v4(struct in_addr from);
-int iface_count(void);
-int iface_count_v4_nl(void);
-const struct in_addr *first_ipv4_iface(void);
-struct interface *get_interface(int n);
-const struct sockaddr_storage *iface_n_sockaddr_storage(int n);
-const struct in_addr *iface_n_ip_v4(int n);
-const struct in_addr *iface_n_bcast_v4(int n);
-const struct sockaddr_storage *iface_n_bcast(int n);
-const struct sockaddr_storage *iface_ip(const struct sockaddr *ip);
-bool iface_local(const struct sockaddr *ip);
-void load_interfaces(void);
-void gfree_interfaces(void);
-bool interfaces_changed(void);
+#include "source3/lib/interface.h"
 
 /* The following definitions come from lib/ldap_debug_handler.c  */
 
diff --git a/source3/lib/interface.h b/source3/lib/interface.h
new file mode 100644
index 00000000000..f45435b4a81
--- /dev/null
+++ b/source3/lib/interface.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * Unix SMB/CIFS implementation.
+ *
+ * Type definitions for interfaces
+ *
+ * Copyright (c) 2020      Andreas Schneider <asn@samba.org>
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _INTERFACE_H
+#define _INTERFACE_H
+
+#include <system/network.h>
+
+bool ismyaddr(const struct sockaddr *ip);
+bool ismyip_v4(struct in_addr ip);
+bool is_local_net(const struct sockaddr *from);
+void setup_linklocal_scope_id(struct sockaddr *pss);
+bool is_local_net_v4(struct in_addr from);
+int iface_count(void);
+int iface_count_v4_nl(void);
+const struct in_addr *first_ipv4_iface(void);
+struct interface *get_interface(int n);
+const struct sockaddr_storage *iface_n_sockaddr_storage(int n);
+const struct in_addr *iface_n_ip_v4(int n);
+const struct in_addr *iface_n_bcast_v4(int n);
+const struct sockaddr_storage *iface_n_bcast(int n);
+const struct sockaddr_storage *iface_ip(const struct sockaddr *ip);
+bool iface_local(const struct sockaddr *ip);
+void load_interfaces(void);
+void gfree_interfaces(void);
+bool interfaces_changed(void);
+
+#endif /* _INTERFACE_H */
-- 
2.29.2


From bd958477d69c820766a30f818163cda9f9d171a3 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 7 Feb 2020 16:48:16 +0100
Subject: [PATCH 076/104] idl: Add SID_SAMBA_SMB3

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 56879ec5876625346df89110f62d52e3fd5b8934)
---
 librpc/idl/security.idl | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl
index a92e8f1518e..06bf7449a70 100644
--- a/librpc/idl/security.idl
+++ b/librpc/idl/security.idl
@@ -282,6 +282,9 @@ interface security
 	const string SID_SAMBA_UNIX_USER_OWNER		= "S-1-22-1";
 	const string SID_SAMBA_UNIX_GROUP_OWNER		= "S-1-22-2";
 
+	/* Information passing via security token */
+	const string SID_SAMBA_SMB3			= "S-1-22-1397571891";
+
 	/* SECURITY_NT_SERVICE */
 	const string NAME_NT_SERVICE            = "NT SERVICE";
 
-- 
2.29.2


From 6b4e237ea0900e2ac7f46b889fd95d1d04db5bff Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 7 Feb 2020 16:48:29 +0100
Subject: [PATCH 077/104] s3:smbd: Add SMB3 connection information to session
 info

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 905c2b9722a64ee57f3fbcff51e6bb591c6e3edc)
---
 source3/include/vfs.h      |  1 +
 source3/smbd/pipes.c       | 82 +++++++++++++++++++++++++++++++++++++-
 source3/smbd/smb2_server.c |  5 +++
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index d527f850628..c0d60636c31 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -411,6 +411,7 @@ typedef struct files_struct {
 		bool use_ofd_locks : 1;
 		bool closing : 1;
 		bool lock_failure_seen : 1;
+		bool encryption_required : 1;
 	} fsp_flags;
 
 	struct tevent_timer *update_write_time_event;
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index 2dd38bb7ab3..d51a3de9497 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -30,13 +30,16 @@
 #include "smbd/globals.h"
 #include "libcli/security/security.h"
 #include "rpc_server/srv_pipe_hnd.h"
+#include "auth/auth_util.h"
 
 NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 		      struct files_struct **pfsp)
 {
+	struct smbXsrv_connection *xconn = smb_req->xconn;
 	struct connection_struct *conn = smb_req->conn;
 	struct files_struct *fsp;
 	struct smb_filename *smb_fname = NULL;
+	struct auth_session_info *session_info = conn->session_info;
 	NTSTATUS status;
 
 	status = file_new(smb_req, conn, &fsp);
@@ -68,10 +71,87 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 		return status;
 	}
 
+	if (smb_req->smb2req != NULL && smb_req->smb2req->was_encrypted) {
+		struct security_token *security_token = NULL;
+		uint16_t dialect = xconn->smb2.server.dialect;
+		uint16_t srv_smb_encrypt = 0x0002;
+		uint16_t cipher = xconn->smb2.server.cipher;
+		char smb3_sid_str[SID_MAX_SIZE];
+		struct dom_sid smb3_dom_sid;
+		struct dom_sid smb3_sid;
+		uint32_t i;
+		bool ok;
+		int rc;
+
+		session_info = copy_session_info(fsp, conn->session_info);
+		if (session_info == NULL) {
+			DBG_ERR("Failed to copy session info\n");
+			file_free(smb_req, fsp);
+			return NT_STATUS_NO_MEMORY;
+		}
+		security_token = session_info->security_token;
+
+		ok = dom_sid_parse(SID_SAMBA_SMB3, &smb3_dom_sid);
+		if (!ok) {
+			file_free(smb_req, fsp);
+			return NT_STATUS_BUFFER_TOO_SMALL;
+		}
+
+		/*
+		 * Security check:
+		 *
+		 * Make sure we don't have a SMB3 SID in the security token!
+		 */
+		for (i = 0; i < security_token->num_sids; i++) {
+			int cmp;
+
+			cmp = dom_sid_compare_domain(&security_token->sids[i],
+						     &smb3_dom_sid);
+			if (cmp == 0) {
+				DBG_ERR("ERROR: An SMB3 SID has already been "
+					"detected in the security token!\n");
+				file_free(smb_req, fsp);
+				return NT_STATUS_ACCESS_DENIED;
+			}
+		}
+
+		rc = snprintf(smb3_sid_str,
+			      sizeof(smb3_sid_str),
+			      "%s-%u-%u-%u",
+			      SID_SAMBA_SMB3,
+			      dialect,
+			      srv_smb_encrypt,
+			      cipher);
+		if (rc < 0) {
+			DBG_ERR("Buffer too small\n");
+			file_free(smb_req, fsp);
+			return NT_STATUS_BUFFER_TOO_SMALL;
+		}
+
+		ok = dom_sid_parse(smb3_sid_str, &smb3_sid);
+		if (!ok) {
+			DBG_ERR("Failed to parse SMB3 SID\n");
+			file_free(smb_req, fsp);
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
+		status = add_sid_to_array_unique(security_token,
+						 &smb3_sid,
+						 &security_token->sids,
+						 &security_token->num_sids);
+		if (!NT_STATUS_IS_OK(status)) {
+			DBG_ERR("Failed to add SMB3 SID to security token\n");
+			file_free(smb_req, fsp);
+			return status;
+		}
+
+		fsp->fsp_flags.encryption_required = true;
+	}
+
 	status = np_open(fsp, name,
 			 conn->sconn->remote_address,
 			 conn->sconn->local_address,
-			 conn->session_info,
+			 session_info,
 			 conn->sconn->ev_ctx,
 			 conn->sconn->msg_ctx,
 			 conn->sconn->dce_ctx,
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index cf9de185c1f..cd24b7d2ed5 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -3232,6 +3232,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
 				return smbd_smb2_request_error(req,
 						NT_STATUS_FILE_CLOSED);
 			}
+		} else {
+			if (fsp->fsp_flags.encryption_required && !req->was_encrypted) {
+				return smbd_smb2_request_error(req,
+						NT_STATUS_ACCESS_DENIED);
+			}
 		}
 	}
 
-- 
2.29.2


From 466c2d98005e1e0a3c3aa7b17779031b426b5da6 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 12 Mar 2020 14:11:56 +0100
Subject: [PATCH 078/104] librpc: Add dcerpc helper
 dcerpc_is_transport_encrypted()

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 8bbe5c8c94aaf75d715f558c363e5b2de49f7bf9)
---
 librpc/rpc/dcerpc_helper.c | 137 +++++++++++++++++++++++++++++++++++++
 librpc/rpc/dcerpc_helper.h |  26 +++++++
 librpc/wscript_build       |   9 +++
 3 files changed, 172 insertions(+)
 create mode 100644 librpc/rpc/dcerpc_helper.c
 create mode 100644 librpc/rpc/dcerpc_helper.h

diff --git a/librpc/rpc/dcerpc_helper.c b/librpc/rpc/dcerpc_helper.c
new file mode 100644
index 00000000000..c5443764628
--- /dev/null
+++ b/librpc/rpc/dcerpc_helper.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2020      Andreas Schneider <asn@samba.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "librpc/gen_ndr/security.h"
+#include "librpc/gen_ndr/auth.h"
+#include "lib/crypto/gnutls_helpers.h"
+#include "libcli/security/dom_sid.h"
+#include "libcli/smb/smb2_constants.h"
+
+#include "dcerpc_helper.h"
+
+static bool smb3_sid_parse(const struct dom_sid *sid,
+			   uint16_t *pdialect,
+			   uint16_t *pencrypt,
+			   uint16_t *pcipher)
+{
+	uint16_t dialect;
+	uint16_t encrypt;
+	uint16_t cipher;
+
+	if (sid->sub_auths[0] != 1397571891) {
+		return false;
+	}
+
+	dialect = sid->sub_auths[1];
+	if (dialect > 0x03ff) {
+		return false;
+	}
+
+	encrypt = sid->sub_auths[2];
+	if (encrypt > 0x0002) {
+		return false;
+	}
+
+	cipher = sid->sub_auths[3];
+	if (cipher > SMB2_ENCRYPTION_AES128_GCM) {
+		return false;
+	}
+
+	if (pdialect != NULL) {
+		*pdialect = dialect;
+	}
+
+	if (pencrypt != NULL) {
+		*pencrypt = encrypt;
+	}
+
+	if (pcipher != NULL) {
+		*pcipher = cipher;
+	}
+
+	return true;
+}
+
+bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info)
+{
+	struct security_token *token = session_info->security_token;
+	struct dom_sid smb3_dom_sid;
+	const struct dom_sid *smb3_sid = NULL;
+	uint16_t dialect = 0;
+	uint16_t encrypt = 0;
+	uint16_t cipher = 0;
+	uint32_t i;
+	bool ok;
+
+	ok = dom_sid_parse(SID_SAMBA_SMB3, &smb3_dom_sid);
+	if (!ok) {
+		return false;
+	}
+
+	for (i = 0; i < token->num_sids; i++) {
+		int cmp;
+
+		/* There is only one SMB3 SID allowed! */
+		cmp = dom_sid_compare_domain(&token->sids[i], &smb3_dom_sid);
+		if (cmp == 0) {
+			if (smb3_sid == NULL) {
+				smb3_sid = &token->sids[i];
+			} else {
+				DBG_ERR("ERROR: The SMB3 SID has been detected "
+					"multiple times\n");
+				return false;
+			}
+		}
+	}
+
+	if (smb3_sid == NULL) {
+		return false;
+	}
+
+	ok = smb3_sid_parse(smb3_sid, &dialect, &encrypt, &cipher);
+	if (!ok) {
+		DBG_ERR("Failed to parse SMB3 SID!\n");
+		return false;
+	}
+
+	DBG_DEBUG("SMB SID - dialect: %#04x, encrypt: %#04x, cipher: %#04x\n",
+		  dialect,
+		  encrypt,
+		  cipher);
+
+	if (dialect < SMB3_DIALECT_REVISION_300) {
+		DBG_DEBUG("Invalid SMB3 dialect!\n");
+		return false;
+	}
+
+	if (encrypt != DCERPC_SMB_ENCRYPTION_REQUIRED) {
+		DBG_DEBUG("Invalid SMB3 encryption!\n");
+		return false;
+	}
+
+	switch (cipher) {
+	case SMB2_ENCRYPTION_AES128_CCM:
+	case SMB2_ENCRYPTION_AES128_GCM:
+		break;
+	default:
+		DBG_DEBUG("Invalid SMB3 cipher!\n");
+		return false;
+	}
+
+	return true;
+}
diff --git a/librpc/rpc/dcerpc_helper.h b/librpc/rpc/dcerpc_helper.h
new file mode 100644
index 00000000000..c0f09ee494e
--- /dev/null
+++ b/librpc/rpc/dcerpc_helper.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2020      Andreas Schneider <asn@samba.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DCERPC_HELPER_H
+#define _DCERPC_HELPER_H
+
+#define DCERPC_SMB_ENCRYPTION_OFF      0x0000
+#define DCERPC_SMB_ENCRYPTION_REQUIRED 0x0002
+
+bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info);
+
+#endif /* _DCERPC_HELPER_H */
diff --git a/librpc/wscript_build b/librpc/wscript_build
index 27b180fa63d..109a1834841 100644
--- a/librpc/wscript_build
+++ b/librpc/wscript_build
@@ -669,6 +669,15 @@ bld.SAMBA_LIBRARY('dcerpc-server-core',
     autoproto='rpc/dcesrv_core_proto.h',
     vnum='0.0.1')
 
+bld.SAMBA_SUBSYSTEM('DCERPC_HELPER',
+                    source='rpc/dcerpc_helper.c',
+                    public_deps='''
+                                samba-hostconfig
+                                samba-security
+                                gnutls
+                                GNUTLS_HELPERS
+                                ''')
+
 bld.SAMBA_SUBSYSTEM('NDR_WINBIND',
 	source='gen_ndr/ndr_winbind.c',
 	public_deps='ndr NDR_LSA'
-- 
2.29.2


From cc8a5479152c6131362e9ca9cfe6e5bab2a71af3 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 28 Aug 2020 16:31:17 +0200
Subject: [PATCH 079/104] s3:smbd: Use defines to set 'srv_smb_encrypt'

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 5f1a73be6311c68a21a550c0de5078baeb78f4ee)
---
 source3/smbd/pipes.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index d51a3de9497..785cbb23b5f 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -31,6 +31,7 @@
 #include "libcli/security/security.h"
 #include "rpc_server/srv_pipe_hnd.h"
 #include "auth/auth_util.h"
+#include "librpc/rpc/dcerpc_helper.h"
 
 NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 		      struct files_struct **pfsp)
@@ -74,7 +75,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name,
 	if (smb_req->smb2req != NULL && smb_req->smb2req->was_encrypted) {
 		struct security_token *security_token = NULL;
 		uint16_t dialect = xconn->smb2.server.dialect;
-		uint16_t srv_smb_encrypt = 0x0002;
+		uint16_t srv_smb_encrypt = DCERPC_SMB_ENCRYPTION_REQUIRED;
 		uint16_t cipher = xconn->smb2.server.cipher;
 		char smb3_sid_str[SID_MAX_SIZE];
 		struct dom_sid smb3_dom_sid;
-- 
2.29.2


From dad6dc0e5a202d48a930504768394343823d5c42 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 12 Nov 2019 16:56:45 +0100
Subject: [PATCH 080/104] s3:rpc_server: Allow to use RC4 for setting passwords

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit c6a21e1897985f267bcfc681179cea95165c3c57)
---
 source3/rpc_server/samr/srv_samr_chgpasswd.c |  3 +
 source3/rpc_server/samr/srv_samr_nt.c        | 78 +++++++++++++++++++-
 source3/rpc_server/wscript_build             |  2 +-
 3 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c
index cb9837ecf01..e326745169e 100644
--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
+++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
@@ -769,11 +769,13 @@ static NTSTATUS check_oem_password(const char *user,
 		.size = 16,
 	};
 
+	GNUTLS_FIPS140_SET_LAX_MODE();
 	rc = gnutls_cipher_init(&cipher_hnd,
 				GNUTLS_CIPHER_ARCFOUR_128,
 				&enc_key,
 				NULL);
 	if (rc < 0) {
+		GNUTLS_FIPS140_SET_STRICT_MODE();
 		return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 	}
 
@@ -781,6 +783,7 @@ static NTSTATUS check_oem_password(const char *user,
 				   password_encrypted,
 				   516);
 	gnutls_cipher_deinit(cipher_hnd);
+	GNUTLS_FIPS140_SET_STRICT_MODE();
 	if (rc < 0) {
 		return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 	}
diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c
index 5ffc3331185..77cb18b6a88 100644
--- a/source3/rpc_server/samr/srv_samr_nt.c
+++ b/source3/rpc_server/samr/srv_samr_nt.c
@@ -46,6 +46,8 @@
 #include "rpc_server/srv_access_check.h"
 #include "../lib/tsocket/tsocket.h"
 #include "lib/util/base64.h"
+#include "param/param.h"
+#include "librpc/rpc/dcerpc_helper.h"
 
 #include "lib/crypto/gnutls_helpers.h"
 #include <gnutls/gnutls.h>
@@ -1887,6 +1889,7 @@ NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
 	char *user_name = NULL;
 	char *rhost;
 	const char *wks = NULL;
+	bool encrypted;
 
 	DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__));
 
@@ -1915,6 +1918,12 @@ NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	encrypted = dcerpc_is_transport_encrypted(p->session_info);
+	if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+	    !encrypted) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	/*
 	 * UNIX username case mangling not required, pass_oem_change
 	 * is case insensitive.
@@ -1948,6 +1957,7 @@ NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
 	char *user_name = NULL;
 	const char *wks = NULL;
 	char *rhost;
+	bool encrypted;
 
 	DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__));
 
@@ -1985,6 +1995,12 @@ NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p,
 		return NT_STATUS_NO_MEMORY;
 	}
 
+	encrypted = dcerpc_is_transport_encrypted(p->session_info);
+	if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+	    !encrypted) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	status = pass_oem_change(user_name,
 				 rhost,
 				 r->in.password->data,
@@ -5200,8 +5216,13 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 	char *rhost;
 	DATA_BLOB session_key;
 	struct dom_sid_buf buf;
+	struct loadparm_context *lp_ctx = NULL;
+	bool encrypted;
 
-	DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__));
+	lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
+	if (lp_ctx == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
 
 	/* This is tricky.  A WinXP domain join sets
 	  (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES)
@@ -5390,13 +5411,27 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 23:
+			encrypted =
+				dcerpc_is_transport_encrypted(p->session_info);
+			if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+			    !encrypted) {
+				status = NT_STATUS_ACCESS_DENIED;
+				break;
+			}
+
 			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			if(!NT_STATUS_IS_OK(status)) {
 				break;
 			}
+			/*
+			 * This can be allowed as it requires a session key
+			 * which we only have if we have a SMB session.
+			 */
+			GNUTLS_FIPS140_SET_LAX_MODE();
 			status = arc4_decrypt_data(session_key,
 						   info->info23.password.data,
 						   516);
+			GNUTLS_FIPS140_SET_STRICT_MODE();
 			if(!NT_STATUS_IS_OK(status)) {
 				break;
 			}
@@ -5412,14 +5447,27 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 24:
+			encrypted =
+				dcerpc_is_transport_encrypted(p->session_info);
+			if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+			    !encrypted) {
+				status = NT_STATUS_ACCESS_DENIED;
+				break;
+			}
 
 			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			if(!NT_STATUS_IS_OK(status)) {
 				break;
 			}
+			/*
+			 * This can be allowed as it requires a session key
+			 * which we only have if we have a SMB session.
+			 */
+			GNUTLS_FIPS140_SET_LAX_MODE();
 			status = arc4_decrypt_data(session_key,
 						   info->info24.password.data,
 						   516);
+			GNUTLS_FIPS140_SET_STRICT_MODE();
 			if(!NT_STATUS_IS_OK(status)) {
 				break;
 			}
@@ -5434,12 +5482,26 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 25:
+			encrypted =
+				dcerpc_is_transport_encrypted(p->session_info);
+			if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+			    !encrypted) {
+				status = NT_STATUS_ACCESS_DENIED;
+				break;
+			}
+
 			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			if(!NT_STATUS_IS_OK(status)) {
 				break;
 			}
+			/*
+			 * This can be allowed as it requires a session key
+			 * which we only have if we have a SMB session.
+			 */
+			GNUTLS_FIPS140_SET_LAX_MODE();
 			status = decode_rc4_passwd_buffer(&session_key,
 					&info->info25.password);
+			GNUTLS_FIPS140_SET_STRICT_MODE();
 			if (!NT_STATUS_IS_OK(status)) {
 				break;
 			}
@@ -5454,12 +5516,26 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p,
 			break;
 
 		case 26:
+			encrypted =
+				dcerpc_is_transport_encrypted(p->session_info);
+			if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+			    !encrypted) {
+				status = NT_STATUS_ACCESS_DENIED;
+				break;
+			}
+
 			status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
 			if(!NT_STATUS_IS_OK(status)) {
 				break;
 			}
+			/*
+			 * This can be allowed as it requires a session key
+			 * which we only have if we have a SMB session.
+			 */
+			GNUTLS_FIPS140_SET_LAX_MODE();
 			status = decode_rc4_passwd_buffer(&session_key,
 					&info->info26.password);
+			GNUTLS_FIPS140_SET_STRICT_MODE();
 			if (!NT_STATUS_IS_OK(status)) {
 				break;
 			}
diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build
index 2af02ad6fa8..eb91ac09384 100644
--- a/source3/rpc_server/wscript_build
+++ b/source3/rpc_server/wscript_build
@@ -85,7 +85,7 @@ bld.SAMBA3_SUBSYSTEM('RPC_SAMR',
                     source='''samr/srv_samr_nt.c
                     samr/srv_samr_util.c
                     samr/srv_samr_chgpasswd.c''',
-                    deps='PLAINTEXT_AUTH SRV_ACCESS_CHECK')
+                    deps='PLAINTEXT_AUTH SRV_ACCESS_CHECK DCERPC_HELPER')
 
 bld.SAMBA3_SUBSYSTEM('RPC_SPOOLSS',
                     source='''spoolss/srv_spoolss_nt.c
-- 
2.29.2


From 2932bdeff6ad18a36b2b64ab59d72ff1040acd09 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 15 Nov 2019 13:49:40 +0100
Subject: [PATCH 081/104] s4:rpc_server: Allow to use RC4 for setting passwords

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit a9c532c6d3e85fbe49b7040254cfc66ab54074bc)
---
 source4/rpc_server/samr/samr_password.c | 30 +++++++++++++++++++++++++
 source4/rpc_server/wscript_build        |  2 +-
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 52a644176e2..83b104fbd0e 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -31,6 +31,8 @@
 #include "../lib/util/util_ldb.h"
 #include "rpc_server/samr/proto.h"
 #include "auth/auth_sam.h"
+#include "lib/param/loadparm.h"
+#include "librpc/rpc/dcerpc_helper.h"
 
 #include "lib/crypto/gnutls_helpers.h"
 #include <gnutls/gnutls.h>
@@ -129,6 +131,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
 	struct dom_sid *user_objectSid = NULL;
 	gnutls_cipher_hd_t cipher_hnd = NULL;
 	gnutls_datum_t lm_session_key;
+	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+	bool encrypted;
 	int rc;
 
 	if (pwbuf == NULL) {
@@ -144,6 +148,12 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
 		return NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER;
 	}
 
+	encrypted = dcerpc_is_transport_encrypted(session_info);
+	if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+	    !encrypted) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	/* Connect to a SAMDB with system privileges for fetching the old pw
 	 * hashes. */
 	sam_ctx = samdb_connect(mem_ctx,
@@ -188,11 +198,13 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
 		.size = sizeof(lm_pwd->hash),
 	};
 
+	GNUTLS_FIPS140_SET_LAX_MODE();
 	rc = gnutls_cipher_init(&cipher_hnd,
 				GNUTLS_CIPHER_ARCFOUR_128,
 				&lm_session_key,
 				NULL);
 	if (rc < 0) {
+		GNUTLS_FIPS140_SET_STRICT_MODE();
 		status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto failed;
 	}
@@ -201,6 +213,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
 				   pwbuf->data,
 				   516);
 	gnutls_cipher_deinit(cipher_hnd);
+	GNUTLS_FIPS140_SET_STRICT_MODE();
 	if (rc < 0) {
 		status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto failed;
@@ -607,7 +620,17 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
 	DATA_BLOB session_key = data_blob(NULL, 0);
 	gnutls_cipher_hd_t cipher_hnd = NULL;
 	gnutls_datum_t _session_key;
+	struct auth_session_info *session_info =
+		dcesrv_call_session_info(dce_call);
+	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
 	int rc;
+	bool encrypted;
+
+	encrypted = dcerpc_is_transport_encrypted(session_info);
+	if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+	    !encrypted) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
 
 	nt_status = dcesrv_transport_session_key(dce_call, &session_key);
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -621,11 +644,17 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
 		.size = session_key.length,
 	};
 
+	/*
+	 * This is safe to support as we only have a session key
+	 * over a SMB connection which we force to be encrypted.
+	 */
+	GNUTLS_FIPS140_SET_LAX_MODE();
 	rc = gnutls_cipher_init(&cipher_hnd,
 				GNUTLS_CIPHER_ARCFOUR_128,
 				&_session_key,
 				NULL);
 	if (rc < 0) {
+		GNUTLS_FIPS140_SET_STRICT_MODE();
 		nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto out;
 	}
@@ -634,6 +663,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call,
 				   pwbuf->data,
 				   516);
 	gnutls_cipher_deinit(cipher_hnd);
+	GNUTLS_FIPS140_SET_STRICT_MODE();
 	if (rc < 0) {
 		nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto out;
diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build
index de55ad6239a..c9c1978f223 100644
--- a/source4/rpc_server/wscript_build
+++ b/source4/rpc_server/wscript_build
@@ -87,7 +87,7 @@ bld.SAMBA_MODULE('dcesrv_samr',
 	autoproto='samr/proto.h',
 	subsystem='dcerpc_server',
 	init_function='dcerpc_server_samr_init',
-	deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS'
+	deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS DCERPC_HELPER'
 	)
 
 
-- 
2.29.2


From 959978865400d20fe1b2f9b5343fbec7c0b1109a Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:45:49 +0200
Subject: [PATCH 082/104] lib:crypto: Add py binding for set_relax/strict fips
 mode

Signed-off-by: Isaac Boukris <iboukris@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 32d4c75d6cbf9153068a0487347097707afb356a)
---
 lib/crypto/py_crypto.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/lib/crypto/py_crypto.c b/lib/crypto/py_crypto.c
index 32b946eee8f..ad18d3ada0f 100644
--- a/lib/crypto/py_crypto.c
+++ b/lib/crypto/py_crypto.c
@@ -24,6 +24,7 @@
 
 #include <gnutls/gnutls.h>
 #include <gnutls/crypto.h>
+#include "lib/crypto/gnutls_helpers.h"
 
 static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args)
 {
@@ -85,12 +86,27 @@ static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args)
 	return result;
 }
 
+static PyObject *py_crypto_set_relax_mode(PyObject *module)
+{
+	GNUTLS_FIPS140_SET_LAX_MODE();
+
+	Py_RETURN_NONE;
+}
+
+static PyObject *py_crypto_set_strict_mode(PyObject *module)
+{
+	GNUTLS_FIPS140_SET_STRICT_MODE();
+
+	Py_RETURN_NONE;
+}
 
 static const char py_crypto_arcfour_crypt_blob_doc[] = "arcfour_crypt_blob(data, key)\n"
 					 "Encrypt the data with RC4 algorithm using the key";
 
 static PyMethodDef py_crypto_methods[] = {
 	{ "arcfour_crypt_blob", (PyCFunction)py_crypto_arcfour_crypt_blob, METH_VARARGS, py_crypto_arcfour_crypt_blob_doc },
+	{ "set_relax_mode", (PyCFunction)py_crypto_set_relax_mode, METH_NOARGS, "Set fips to relax mode" },
+	{ "set_strict_mode", (PyCFunction)py_crypto_set_strict_mode, METH_NOARGS, "Set fips to strict mode" },
 	{0},
 };
 
-- 
2.29.2


From e3059d24a83175efb4f9eb3844c2e02d2af7775a Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 28 Oct 2020 17:05:36 +0100
Subject: [PATCH 083/104] s4:param: Add 'weak crypto' getter to pyparam

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 7d54e4b49c235dc571f47d15e6b0a6fa63340773)
---
 source4/param/pyparam.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c
index 4023fac4dd6..e15592b5743 100644
--- a/source4/param/pyparam.c
+++ b/source4/param/pyparam.c
@@ -463,6 +463,23 @@ static PyObject *py_lp_ctx_config_file(PyObject *self, void *closure)
 		return PyUnicode_FromString(configfile);
 }
 
+static PyObject *py_lp_ctx_weak_crypto(PyObject *self, void *closure)
+{
+	enum samba_weak_crypto weak_crypto =
+		lpcfg_weak_crypto(PyLoadparmContext_AsLoadparmContext(self));
+
+	switch(weak_crypto) {
+	case SAMBA_WEAK_CRYPTO_UNKNOWN:
+		Py_RETURN_NONE;
+	case SAMBA_WEAK_CRYPTO_ALLOWED:
+		return PyUnicode_FromString("allowed");
+	case SAMBA_WEAK_CRYPTO_DISALLOWED:
+		return PyUnicode_FromString("disallowed");
+	}
+
+	Py_RETURN_NONE;
+}
+
 static PyGetSetDef py_lp_ctx_getset[] = {
 	{
 		.name = discard_const_p(char, "default_service"),
@@ -473,6 +490,11 @@ static PyGetSetDef py_lp_ctx_getset[] = {
 		.get  = (getter)py_lp_ctx_config_file,
 		.doc  = discard_const_p(char, "Name of last config file that was loaded.")
 	},
+	{
+		.name = discard_const_p(char, "weak_crypto"),
+		.get  = (getter)py_lp_ctx_weak_crypto,
+		.doc  = discard_const_p(char, "If weak crypto is allowed.")
+	},
 	{ .name = NULL }
 };
 
-- 
2.29.2


From 2c10e3c1bbd7527f8563dca42700310c86ec04d4 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 21 Oct 2020 10:09:22 +0200
Subject: [PATCH 084/104] python:tests: Add SAMR password change tests for fips

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 9a3ba502d8193b25799ef92917efafd52de2e8c2)
---
 .../tests/dcerpc/samr_change_password.py      | 188 ++++++++++++++++++
 selftest/tests.py                             |   2 +
 2 files changed, 190 insertions(+)
 create mode 100644 python/samba/tests/dcerpc/samr_change_password.py

diff --git a/python/samba/tests/dcerpc/samr_change_password.py b/python/samba/tests/dcerpc/samr_change_password.py
new file mode 100644
index 00000000000..109eeea98cc
--- /dev/null
+++ b/python/samba/tests/dcerpc/samr_change_password.py
@@ -0,0 +1,188 @@
+# Unix SMB/CIFS implementation.
+#
+# Copyright © 2020 Andreas Schneider <asn@samba.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""Tests for samba.dcerpc.samr.password"""
+
+import os
+import ctypes
+import samba.tests
+
+from samba import crypto, generate_random_password, generate_random_bytes, ntstatus
+from samba.auth import system_session
+from samba.credentials import Credentials
+from samba.credentials import SMB_ENCRYPTION_REQUIRED
+from samba.dcerpc import samr, security, lsa
+from samba.samdb import SamDB
+from samba.tests import RpcInterfaceTestCase
+
+
+class SamrPasswordTests(RpcInterfaceTestCase):
+    def setUp(self):
+        super(SamrPasswordTests, self).setUp()
+        self.open_samdb()
+
+        self.create_user_account(10000)
+
+        self.remote_server = samba.tests.env_get_var_value('SERVER')
+        self.remote_domain = samba.tests.env_get_var_value('DOMAIN')
+        self.remote_user = samba.tests.env_get_var_value('USERNAME')
+        self.remote_password = samba.tests.env_get_var_value('PASSWORD')
+        self.remote_binding_string = "ncacn_np:%s[krb5]" % (self.remote_server)
+
+        self.remote_creds = Credentials()
+        self.remote_creds.guess(self.lp)
+        self.remote_creds.set_username(self.remote_user)
+        self.remote_creds.set_password(self.remote_password)
+
+    def tearDown(self):
+        super(SamrPasswordTests, self).tearDown()
+
+        samr.Close(self.user_handle)
+        samr.Close(self.domain_handle)
+        samr.Close(self.handle)
+
+        samba.tests.delete_force(self.samdb, self.user_dn)
+
+    #
+    # Open the samba database
+    #
+    def open_samdb(self):
+        self.lp = samba.tests.env_loadparm()
+
+        self.local_creds = Credentials()
+        self.local_creds.guess(self.lp)
+        self.session = system_session()
+        self.samdb = SamDB(session_info=self.session,
+                           credentials=self.local_creds,
+                           lp=self.lp)
+
+    #
+    # Open a SAMR Domain handle
+    #
+    def open_domain_handle(self):
+        self.handle = self.conn.Connect2(None,
+                                         security.SEC_FLAG_MAXIMUM_ALLOWED)
+
+        self.domain_sid = self.conn.LookupDomain(self.handle,
+                                                 lsa.String(self.remote_domain))
+
+        self.domain_handle = self.conn.OpenDomain(self.handle,
+                                                  security.SEC_FLAG_MAXIMUM_ALLOWED,
+                                                  self.domain_sid)
+
+    def open_user_handle(self):
+        name = lsa.String(self.user_name)
+
+        rids = self.conn.LookupNames(self.domain_handle, [name])
+
+        self.user_handle = self.conn.OpenUser(self.domain_handle,
+                                              security.SEC_FLAG_MAXIMUM_ALLOWED,
+                                              rids[0].ids[0])
+    #
+    # Create a test user account
+    #
+    def create_user_account(self, user_id):
+        self.user_name = ("SAMR_USER_%d" % user_id)
+        self.user_pass = generate_random_password(32, 32)
+        self.user_dn = "cn=%s,cn=users,%s" % (self.user_name, self.samdb.domain_dn())
+
+        samba.tests.delete_force(self.samdb, self.user_dn)
+
+        self.samdb.newuser(self.user_name,
+                           self.user_pass,
+                           description="Password for " + self.user_name + " is " + self.user_pass,
+                           givenname=self.user_name,
+                           surname=self.user_name)
+
+
+    def init_samr_CryptPassword(self, password, session_key):
+
+        def encode_pw_buffer(password):
+            data = bytearray([0] * 516)
+
+            p = samba.string_to_byte_array(password.encode('utf-16-le'))
+            plen = len(p)
+
+            b = generate_random_bytes(512 - plen)
+
+            i = 512 - plen
+            data[0:i] = b
+            data[i:i+plen] = p
+            data[512:516] = plen.to_bytes(4, byteorder='little')
+
+            return bytes(data)
+
+        # This is a test, so always allow to encrypt using RC4
+        try:
+            crypto.set_relax_mode()
+            encrypted_blob = samba.arcfour_encrypt(session_key, encode_pw_buffer(password))
+        finally:
+            crypto.set_strict_mode()
+
+        out_blob = samr.CryptPassword()
+        out_blob.data = list(encrypted_blob)
+
+        return out_blob
+
+
+    def test_setUserInfo2_Password(self, password='P@ssw0rd'):
+        self.conn = samr.samr(self.remote_binding_string,
+                              self.get_loadparm(),
+                              self.remote_creds)
+        self.open_domain_handle()
+        self.open_user_handle()
+
+        password='P@ssw0rd'
+
+        level = 24
+        info = samr.UserInfo24()
+
+        info.password_expired = 0
+        info.password = self.init_samr_CryptPassword(password, self.conn.session_key)
+
+        # If the server is in FIPS mode, it should reject the password change!
+        try:
+            self.conn.SetUserInfo2(self.user_handle, level, info)
+        except samba.NTSTATUSError as e:
+            code = ctypes.c_uint32(e.args[0]).value
+            print(code)
+            if ((code == ntstatus.NT_STATUS_ACCESS_DENIED) and
+                (self.lp.weak_crypto == 'disallowed')):
+                pass
+            else:
+                raise
+
+
+    def test_setUserInfo2_Password_Encrypted(self, password='P@ssw0rd'):
+        self.remote_creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+
+        self.conn = samr.samr(self.remote_binding_string,
+                              self.get_loadparm(),
+                              self.remote_creds)
+        self.open_domain_handle()
+        self.open_user_handle()
+
+        password='P@ssw0rd'
+
+        level = 24
+        info = samr.UserInfo24()
+
+        info.password_expired = 0
+        info.password = self.init_samr_CryptPassword(password, self.conn.session_key)
+
+        self.conn.SetUserInfo2(self.user_handle, level, info)
diff --git a/selftest/tests.py b/selftest/tests.py
index adcb5b53189..86cab3f8046 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -93,6 +93,8 @@ planpythontestsuite(
                 os.path.join(samba4srcdir, "..", "third_party", "waf")])
 planpythontestsuite("fileserver", "samba.tests.smbd_fuzztest")
 planpythontestsuite("nt4_dc_smb1", "samba.tests.dcerpc.binding")
+for env in [ 'ad_dc:local', 'ad_dc_fips:local' ]:
+    planpythontestsuite(env, "samba.tests.dcerpc.samr_change_password")
 
 
 def cmdline(script, *args):
-- 
2.29.2


From 65f6aef76ebc4b432f2743fb36cec64d7e06e71d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 21 Oct 2020 10:09:22 +0200
Subject: [PATCH 085/104] python:tests: Add SAMR password change tests for fips

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>

Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Thu Oct 29 15:41:37 UTC 2020 on sn-devel-184

(cherry picked from commit ebd687335b9accfdbae7dbc65c9882ab4d5c0986)
---
 selftest/target/Samba4.pm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 649e923ff9a..1ebdf2a5484 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1040,7 +1040,7 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname}
 	$samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
 	$samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
 	$samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
-	    . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
+	    . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account' -d10";
 	unless (system($samba_tool_cmd) == 0) {
 		warn("Unable to add '$testallowed_account' user to 'Allowed RODC Password Replication Group': \n$samba_tool_cmd\n");
 		return undef;
-- 
2.29.2


From 114ce58de5ac14035c095e12aeb31931c7859d89 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 20 Aug 2020 09:40:41 +0200
Subject: [PATCH 086/104] auth:creds: Rename CRED_USE_KERBEROS values

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 1298280a22ef7494fb85a6a5953bae15d22fa204)
---
 auth/credentials/credentials.c         |  8 +++++---
 auth/credentials/credentials.h         |  9 ++++++---
 auth/credentials/credentials_krb5.c    |  4 ++--
 auth/credentials/credentials_ntlm.c    |  2 +-
 auth/credentials/credentials_secrets.c |  5 +++--
 auth/credentials/pycredentials.c       |  6 +++---
 auth/credentials/tests/simple.c        |  2 +-
 auth/credentials/wscript_build         |  2 +-
 auth/gensec/gensec_start.c             |  8 ++++----
 examples/winexe/winexe.c               |  4 ++--
 source3/auth/auth_generic.c            |  4 ++--
 source3/lib/util_cmdline.c             | 18 +++++++++---------
 source3/libads/sasl.c                  |  8 ++++----
 source3/libnet/libnet_join.c           |  2 +-
 source3/libsmb/cliconnect.c            | 16 ++++++++--------
 source3/passdb/passdb.c                |  6 +++---
 source3/passdb/pdb_samba_dsdb.c        |  4 ++--
 source3/rpc_client/cli_pipe.c          |  2 +-
 source3/rpcclient/rpcclient.c          |  8 ++++----
 source3/utils/net_ads.c                |  2 +-
 source3/utils/net_util.c               |  6 +++---
 source3/utils/ntlm_auth.c              |  4 ++--
 source3/winbindd/winbindd_cm.c         |  2 +-
 source4/auth/gensec/gensec_gssapi.c    |  2 +-
 source4/auth/session.c                 |  2 +-
 source4/lib/cmdline/popt_credentials.c |  4 ++--
 source4/torture/ldap/session_expiry.c  |  2 +-
 source4/torture/raw/session.c          |  4 ++--
 source4/torture/rpc/schannel.c         |  4 ++--
 source4/torture/smb2/session.c         | 12 ++++++------
 30 files changed, 84 insertions(+), 78 deletions(-)

diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c
index 77c35dd104b..1bdd6f15a09 100644
--- a/auth/credentials/credentials.c
+++ b/auth/credentials/credentials.c
@@ -44,6 +44,8 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
 
 	cred->winbind_separator = '\\';
 
+	cred->use_kerberos = CRED_USE_KERBEROS_DESIRED;
+
 	cred->signing_state = SMB_SIGNING_DEFAULT;
 
 	/*
@@ -360,7 +362,7 @@ _PUBLIC_ bool cli_credentials_authentication_requested(struct cli_credentials *c
 		return true;
 	}
 
-	if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) {
+	if (cli_credentials_get_kerberos_state(cred) == CRED_USE_KERBEROS_REQUIRED) {
 		return true;
 	}
 
@@ -1018,7 +1020,7 @@ _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred,
 	}
 	
 	if (lp_ctx != NULL &&
-	    cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) {
+	    cli_credentials_get_kerberos_state(cred) != CRED_USE_KERBEROS_DISABLED) {
 		cli_credentials_set_ccache(cred, lp_ctx, NULL, CRED_GUESS_FILE,
 					   &error_string);
 	}
@@ -1097,7 +1099,7 @@ _PUBLIC_ void cli_credentials_set_anonymous(struct cli_credentials *cred)
 	cli_credentials_set_principal(cred, NULL, CRED_SPECIFIED);
 	cli_credentials_set_realm(cred, NULL, CRED_SPECIFIED);
 	cli_credentials_set_workstation(cred, "", CRED_UNINITIALISED);
-	cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS);
+	cli_credentials_set_kerberos_state(cred, CRED_USE_KERBEROS_DISABLED);
 }
 
 /**
diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h
index 438bcdce232..f468b8558dd 100644
--- a/auth/credentials/credentials.h
+++ b/auth/credentials/credentials.h
@@ -53,9 +53,12 @@ enum credentials_obtained {
 };
 
 enum credentials_use_kerberos {
-	CRED_AUTO_USE_KERBEROS = 0, /* Default, we try kerberos if available */
-	CRED_DONT_USE_KERBEROS,     /* Sometimes trying kerberos just does 'bad things', so don't */
-	CRED_MUST_USE_KERBEROS      /* Sometimes administrators are parinoid, so always do kerberos */
+	/** Sometimes trying kerberos just does 'bad things', so don't */
+	CRED_USE_KERBEROS_DISABLED = 0,
+	/** Default, we try kerberos if available */
+	CRED_USE_KERBEROS_DESIRED,
+	/** Sometimes administrators are paranoid, so always do kerberos */
+	CRED_USE_KERBEROS_REQUIRED,
 };
 
 enum credentials_krb_forwardable {
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index 259b35b73b0..36f6b59a72b 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -871,7 +871,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred,
 	ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
 					 &ccache, error_string);
 	if (ret) {
-		if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) {
+		if (cli_credentials_get_kerberos_state(cred) == CRED_USE_KERBEROS_REQUIRED) {
 			DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", *error_string));
 		} else {
 			DEBUG(4, ("Failed to get kerberos credentials: %s\n", *error_string));
@@ -1431,7 +1431,7 @@ _PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials *
 	cred->impersonate_principal = talloc_strdup(cred, principal);
 	talloc_free(cred->self_service);
 	cred->self_service = talloc_strdup(cred, self_service);
-	cli_credentials_set_kerberos_state(cred, CRED_MUST_USE_KERBEROS);
+	cli_credentials_set_kerberos_state(cred, CRED_USE_KERBEROS_REQUIRED);
 }
 
 /*
diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c
index f1b22a6c9e2..1bec60e5dce 100644
--- a/auth/credentials/credentials_ntlm.c
+++ b/auth/credentials/credentials_ntlm.c
@@ -53,7 +53,7 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred
 	const struct samr_Password *nt_hash = NULL;
 	int rc;
 
-	if (cred->use_kerberos == CRED_MUST_USE_KERBEROS) {
+	if (cred->use_kerberos == CRED_USE_KERBEROS_REQUIRED) {
 		TALLOC_FREE(frame);
 		return NT_STATUS_INVALID_PARAMETER_MIX;
 	}
diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c
index 52a89d4d5b4..58067a5bece 100644
--- a/auth/credentials/credentials_secrets.c
+++ b/auth/credentials/credentials_secrets.c
@@ -370,7 +370,8 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credenti
 	}
 
 	if (secrets_tdb_password_more_recent) {
-		enum credentials_use_kerberos use_kerberos = CRED_DONT_USE_KERBEROS;
+		enum credentials_use_kerberos use_kerberos =
+			CRED_USE_KERBEROS_DISABLED;
 		char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx));
 		cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED);
 		cli_credentials_set_old_password(cred, secrets_tdb_old_password, CRED_SPECIFIED);
@@ -386,7 +387,7 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credenti
 
 				FALL_THROUGH;
 			case ROLE_ACTIVE_DIRECTORY_DC:
-				use_kerberos = CRED_AUTO_USE_KERBEROS;
+				use_kerberos = CRED_USE_KERBEROS_DESIRED;
 				break;
 			}
 		}
diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c
index 17c90573f09..95dde276ef7 100644
--- a/auth/credentials/pycredentials.c
+++ b/auth/credentials/pycredentials.c
@@ -1492,9 +1492,9 @@ MODULE_INIT_FUNC(credentials)
 	PyModule_AddObject(m, "CALLBACK_RESULT", PyLong_FromLong(CRED_CALLBACK_RESULT));
 	PyModule_AddObject(m, "SPECIFIED", PyLong_FromLong(CRED_SPECIFIED));
 
-	PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyLong_FromLong(CRED_AUTO_USE_KERBEROS));
-	PyModule_AddObject(m, "DONT_USE_KERBEROS", PyLong_FromLong(CRED_DONT_USE_KERBEROS));
-	PyModule_AddObject(m, "MUST_USE_KERBEROS", PyLong_FromLong(CRED_MUST_USE_KERBEROS));
+	PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_DESIRED));
+	PyModule_AddObject(m, "DONT_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_DISABLED));
+	PyModule_AddObject(m, "MUST_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_REQUIRED));
 
 	PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE",  PyLong_FromLong(CRED_AUTO_KRB_FORWARDABLE));
 	PyModule_AddObject(m, "NO_KRB_FORWARDABLE",    PyLong_FromLong(CRED_NO_KRB_FORWARDABLE));
diff --git a/auth/credentials/tests/simple.c b/auth/credentials/tests/simple.c
index 7f122bed3bc..b39d7a2251b 100644
--- a/auth/credentials/tests/simple.c
+++ b/auth/credentials/tests/simple.c
@@ -73,7 +73,7 @@ static bool test_guess(struct torture_context *tctx)
 	const char *passwd_fd = getenv("PASSWD_FD");
 	const char *passwd_file = getenv("PASSWD_FILE");
 
-	cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS);
+	cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_REQUIRED);
 
 	unsetenv("USER");
 	unsetenv("PASSWD_FD");
diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build
index 1e3302e3e48..ad16b7d8008 100644
--- a/auth/credentials/wscript_build
+++ b/auth/credentials/wscript_build
@@ -5,7 +5,7 @@ bld.SAMBA_LIBRARY('samba-credentials',
 	public_headers='credentials.h',
 	pc_files='samba-credentials.pc',
 	deps='LIBCRYPTO samba-errors events LIBCLI_AUTH samba-security CREDENTIALS_SECRETS CREDENTIALS_KRB5',
-	vnum='0.1.0'
+	vnum='1.0.0'
 	)
 
 bld.SAMBA_SUBSYSTEM('CREDENTIALS_KRB5',
diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index 3f42d611140..56306efed13 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -117,18 +117,18 @@ static const struct gensec_security_ops **gensec_use_kerberos_mechs(
 		}
 
 		switch (use_kerberos) {
-		case CRED_AUTO_USE_KERBEROS:
+		case CRED_USE_KERBEROS_DESIRED:
 			keep = true;
 			break;
 
-		case CRED_DONT_USE_KERBEROS:
+		case CRED_USE_KERBEROS_DISABLED:
 			if (old_gensec_list[i]->kerberos == false) {
 				keep = true;
 			}
 
 			break;
 
-		case CRED_MUST_USE_KERBEROS:
+		case CRED_USE_KERBEROS_REQUIRED:
 			if (old_gensec_list[i]->kerberos == true) {
 				keep = true;
 			}
@@ -156,7 +156,7 @@ _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs(
 				TALLOC_CTX *mem_ctx)
 {
 	const struct gensec_security_ops * const *backends = gensec_security_all();
-	enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS;
+	enum credentials_use_kerberos use_kerberos = CRED_USE_KERBEROS_DESIRED;
 	bool keep_schannel = false;
 
 	if (gensec_security != NULL) {
diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c
index 03e7ec85198..95386211c0a 100644
--- a/examples/winexe/winexe.c
+++ b/examples/winexe/winexe.c
@@ -283,8 +283,8 @@ static void parse_args(int argc, const char *argv[],
 	if (opt_kerberos) {
 		cli_credentials_set_kerberos_state(cred,
 		                                   strcmp(opt_kerberos, "yes")
-		                                   ? CRED_MUST_USE_KERBEROS
-		                                   : CRED_DONT_USE_KERBEROS);
+		                                   ? CRED_USE_KERBEROS_REQUIRED
+		                                   : CRED_USE_KERBEROS_DISABLED);
 	}
 
 	if (options->runas == NULL && options->runas_file != NULL) {
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
index 0e9500ac08d..f314acd9559 100644
--- a/source3/auth/auth_generic.c
+++ b/source3/auth/auth_generic.c
@@ -356,9 +356,9 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
 		cli_credentials_set_conf(server_credentials, lp_ctx);
 
 		if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
-			cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
+			cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DESIRED);
 		} else {
-			cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
+			cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DISABLED);
 		}
 
 		nt_status = gensec_server_start(tmp_ctx, gensec_settings,
diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c
index 9c9e2f0ac0f..d2af34ee19b 100644
--- a/source3/lib/util_cmdline.c
+++ b/source3/lib/util_cmdline.c
@@ -307,9 +307,9 @@ void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info,
 	enum credentials_use_kerberos krb5_state;
 
 	if (b) {
-		krb5_state = CRED_MUST_USE_KERBEROS;
+		krb5_state = CRED_USE_KERBEROS_REQUIRED;
 	} else {
-		krb5_state = CRED_DONT_USE_KERBEROS;
+		krb5_state = CRED_USE_KERBEROS_DISABLED;
 	}
 
 	cli_credentials_set_kerberos_state(auth_info->creds, krb5_state);
@@ -321,7 +321,7 @@ bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info)
 
 	krb5_state = cli_credentials_get_kerberos_state(auth_info->creds);
 
-	if (krb5_state == CRED_MUST_USE_KERBEROS) {
+	if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
 		return true;
 	}
 
@@ -336,17 +336,17 @@ void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_i
 	krb5_state = cli_credentials_get_kerberos_state(auth_info->creds);
 
 	switch (krb5_state) {
-	case CRED_MUST_USE_KERBEROS:
+	case CRED_USE_KERBEROS_REQUIRED:
 		if (b) {
-			krb5_state = CRED_AUTO_USE_KERBEROS;
+			krb5_state = CRED_USE_KERBEROS_DESIRED;
 		}
 		break;
-	case CRED_AUTO_USE_KERBEROS:
+	case CRED_USE_KERBEROS_DESIRED:
 		if (!b) {
-			krb5_state = CRED_MUST_USE_KERBEROS;
+			krb5_state = CRED_USE_KERBEROS_REQUIRED;
 		}
 		break;
-	case CRED_DONT_USE_KERBEROS:
+	case CRED_USE_KERBEROS_DISABLED:
 		/* nothing to do */
 		break;
 	}
@@ -360,7 +360,7 @@ bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info *
 
 	krb5_state = cli_credentials_get_kerberos_state(auth_info->creds);
 
-	if (krb5_state == CRED_AUTO_USE_KERBEROS) {
+	if (krb5_state == CRED_USE_KERBEROS_DESIRED) {
 		return true;
 	}
 
diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c
index 87beeafe3ed..90ffa040ec0 100644
--- a/source3/libads/sasl.c
+++ b/source3/libads/sasl.c
@@ -158,7 +158,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads,
 		use_spnego_principal = false;
 	}
 
-	if (krb5_state == CRED_DONT_USE_KERBEROS) {
+	if (krb5_state == CRED_USE_KERBEROS_DISABLED) {
 		use_spnego_principal = false;
 	}
 
@@ -565,7 +565,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
 		{
 
 			status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
-							     CRED_MUST_USE_KERBEROS,
+							     CRED_USE_KERBEROS_REQUIRED,
 							     p.service, p.hostname,
 							     blob);
 			if (ADS_ERR_OK(status)) {
@@ -581,7 +581,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
 
 		if (ADS_ERR_OK(status)) {
 			status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
-							CRED_MUST_USE_KERBEROS,
+							CRED_USE_KERBEROS_REQUIRED,
 							p.service, p.hostname,
 							blob);
 			if (!ADS_ERR_OK(status)) {
@@ -616,7 +616,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
 	   library for HMAC_MD4 encryption */
 	mech = "NTLMSSP";
 	status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO",
-					     CRED_DONT_USE_KERBEROS,
+					     CRED_USE_KERBEROS_DISABLED,
 					     p.service, p.hostname,
 					     data_blob_null);
 done:
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index f3bf27e6c00..bd3aeec9434 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -1707,7 +1707,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx,
 
 	if (use_kerberos) {
 		cli_credentials_set_kerberos_state(cli_creds,
-				CRED_MUST_USE_KERBEROS);
+				CRED_USE_KERBEROS_REQUIRED);
 	}
 
 	status = cli_full_connection_creds(&cli, NULL,
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index abfd18bfaf1..f7b4741de89 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -124,13 +124,13 @@ struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx,
 
 	if (use_kerberos && fallback_after_kerberos) {
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_AUTO_USE_KERBEROS);
+						   CRED_USE_KERBEROS_DESIRED);
 	} else if (use_kerberos) {
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_MUST_USE_KERBEROS);
+						   CRED_USE_KERBEROS_REQUIRED);
 	} else {
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_DONT_USE_KERBEROS);
+						   CRED_USE_KERBEROS_DISABLED);
 	}
 
 	if (use_ccache) {
@@ -255,7 +255,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
 
 	krb5_state = cli_credentials_get_kerberos_state(creds);
 
-	if (krb5_state != CRED_DONT_USE_KERBEROS) {
+	if (krb5_state != CRED_USE_KERBEROS_DISABLED) {
 		try_kerberos = true;
 	}
 
@@ -275,7 +275,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
 		try_kerberos = false;
 	}
 
-	if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) {
+	if (krb5_state == CRED_USE_KERBEROS_REQUIRED && !try_kerberos) {
 		DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access "
 			  "'%s' not possible\n",
 			  user_principal, user_domain, user_account,
@@ -286,7 +286,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
 
 	if (pass == NULL || strlen(pass) == 0) {
 		need_kinit = false;
-	} else if (krb5_state == CRED_MUST_USE_KERBEROS) {
+	} else if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
 		need_kinit = try_kerberos;
 	} else {
 		need_kinit = try_kerberos;
@@ -321,14 +321,14 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli,
 	if (ret != 0) {
 		int dbglvl = DBGLVL_NOTICE;
 
-		if (krb5_state == CRED_MUST_USE_KERBEROS) {
+		if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
 			dbglvl = DBGLVL_ERR;
 		}
 
 		DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n",
 			       user_principal, target_hostname,
 			       error_message(ret)));
-		if (krb5_state == CRED_MUST_USE_KERBEROS) {
+		if (krb5_state == CRED_USE_KERBEROS_REQUIRED) {
 			TALLOC_FREE(frame);
 			return krb5_to_nt_status(ret);
 		}
diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c
index 8ed1bafcea3..b12c845d9d2 100644
--- a/source3/passdb/passdb.c
+++ b/source3/passdb/passdb.c
@@ -2630,7 +2630,7 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
 		/*
 		 * It's not possible to use NTLMSSP with a domain trust account.
 		 */
-		cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS);
+		cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_REQUIRED);
 	} else {
 		/*
 		 * We can't use kerberos against an NT4 domain.
@@ -2638,7 +2638,7 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
 		 * We should have a mode that also disallows NTLMSSP here,
 		 * as only NETLOGON SCHANNEL is possible.
 		 */
-		cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
+		cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_DISABLED);
 	}
 
 	ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED);
@@ -2656,7 +2656,7 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
 		/*
 		 * We currently can't do kerberos just with an NTHASH.
 		 */
-		cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
+		cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_DISABLED);
 		goto done;
 	}
 
diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c
index 276bda88efc..93e8f5bebe6 100644
--- a/source3/passdb/pdb_samba_dsdb.c
+++ b/source3/passdb/pdb_samba_dsdb.c
@@ -2599,13 +2599,13 @@ static NTSTATUS pdb_samba_dsdb_get_trusteddom_creds(struct pdb_methods *m,
 		 * Force kerberos if this is an active directory domain
 		 */
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_MUST_USE_KERBEROS);
+						   CRED_USE_KERBEROS_REQUIRED);
 	} else  {
 		/*
 		 * TODO: we should allow krb5 with the raw nt hash.
 		 */
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_DONT_USE_KERBEROS);
+						   CRED_USE_KERBEROS_DISABLED);
 	}
 
 	*_creds = talloc_move(mem_ctx, &creds);
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 8227ef0b0bd..ba6c86cc227 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -2637,7 +2637,7 @@ NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx,
 					NAME_NT_AUTHORITY, /* domain */
 					"SYSTEM",
 					NULL, /* password */
-					CRED_DONT_USE_KERBEROS,
+					CRED_USE_KERBEROS_DISABLED,
 					NULL, /* netlogon_creds_CredentialState */
 					presult);
 }
diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c
index 575a42ebf70..a38f69f5592 100644
--- a/source3/rpcclient/rpcclient.c
+++ b/source3/rpcclient/rpcclient.c
@@ -810,19 +810,19 @@ static NTSTATUS do_cmd(struct cli_state *cli,
 		case DCERPC_AUTH_TYPE_SPNEGO:
 			switch (pipe_default_auth_spnego_type) {
 			case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
-				krb5_state = CRED_DONT_USE_KERBEROS;
+				krb5_state = CRED_USE_KERBEROS_DISABLED;
 				break;
 			case PIPE_AUTH_TYPE_SPNEGO_KRB5:
-				krb5_state = CRED_MUST_USE_KERBEROS;
+				krb5_state = CRED_USE_KERBEROS_REQUIRED;
 				break;
 			case PIPE_AUTH_TYPE_SPNEGO_NONE:
-				krb5_state = CRED_AUTO_USE_KERBEROS;
+				krb5_state = CRED_USE_KERBEROS_DESIRED;
 				break;
 			}
 			FALL_THROUGH;
 		case DCERPC_AUTH_TYPE_NTLMSSP:
 		case DCERPC_AUTH_TYPE_KRB5:
-			if (krb5_state != CRED_AUTO_USE_KERBEROS) {
+			if (krb5_state != CRED_USE_KERBEROS_DESIRED) {
 				cli_credentials_set_kerberos_state(creds,
 								   krb5_state);
 			}
diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
index 7f5b9c3a440..1a0e8a5c9dd 100644
--- a/source3/utils/net_ads.c
+++ b/source3/utils/net_ads.c
@@ -2432,7 +2432,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char *
 		talloc_destroy(mem_ctx);
 		return -1;
 	}
-	cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS);
+	cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_REQUIRED);
 
 	nt_status = cli_full_connection_creds(&cli, lp_netbios_name(), servername,
 					&server_ss, 0,
diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c
index 5829d891075..6c5321db0fd 100644
--- a/source3/utils/net_util.c
+++ b/source3/utils/net_util.c
@@ -493,13 +493,13 @@ struct cli_credentials *net_context_creds(struct net_context *c,
 
 	if (c->opt_kerberos && c->opt_user_specified) {
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_AUTO_USE_KERBEROS);
+						   CRED_USE_KERBEROS_DESIRED);
 	} else if (c->opt_kerberos) {
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_MUST_USE_KERBEROS);
+						   CRED_USE_KERBEROS_REQUIRED);
 	} else {
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_DONT_USE_KERBEROS);
+						   CRED_USE_KERBEROS_DISABLED);
 	}
 
 	if (c->opt_ccache) {
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 7f8d2688978..bfaeff5188d 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -1364,9 +1364,9 @@ static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx,
 	cli_credentials_set_conf(server_credentials, lp_ctx);
 
 	if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
-		cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
+		cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DESIRED);
 	} else {
-		cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
+		cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DISABLED);
 	}
 
 	nt_status = gensec_server_start(tmp_ctx, gensec_settings,
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index 5fb22d7e9c8..466a0095ef2 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -706,7 +706,7 @@ static NTSTATUS cm_get_ipc_credentials(TALLOC_CTX *mem_ctx,
 	}
 
 	cli_credentials_set_conf(creds, lp_ctx);
-	cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
+	cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_DISABLED);
 
 	ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
 	if (!ok) {
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index d66abf32a7f..b668d4ed258 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -1556,7 +1556,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
 		}
 		
 		/* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */
-		cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS);
+		cli_credentials_set_kerberos_state(session_info->credentials, CRED_USE_KERBEROS_REQUIRED);
 
 		/* It has been taken from this place... */
 		gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
diff --git a/source4/auth/session.c b/source4/auth/session.c
index c5fc226a7d7..8e44dcd24f1 100644
--- a/source4/auth/session.c
+++ b/source4/auth/session.c
@@ -295,7 +295,7 @@ struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx,
 		/* This credential handle isn't useful for password
 		 * authentication, so ensure nobody tries to do that */
 		cli_credentials_set_kerberos_state(creds,
-						   CRED_MUST_USE_KERBEROS);
+						   CRED_USE_KERBEROS_REQUIRED);
 
 	}
 #endif
diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c
index 5dd61f6339c..7d8963da99e 100644
--- a/source4/lib/cmdline/popt_credentials.c
+++ b/source4/lib/cmdline/popt_credentials.c
@@ -120,8 +120,8 @@ static void popt_common_credentials_callback(poptContext con,
 		cli_credentials_set_kerberos_state(
 			popt_get_cmdline_credentials(),
 						   use_kerberos 
-						   ? CRED_MUST_USE_KERBEROS
-						   : CRED_DONT_USE_KERBEROS);
+						   ? CRED_USE_KERBEROS_REQUIRED
+						   : CRED_USE_KERBEROS_DISABLED);
 		break;
 	}
 		
diff --git a/source4/torture/ldap/session_expiry.c b/source4/torture/ldap/session_expiry.c
index 35dda439b17..e5e38450745 100644
--- a/source4/torture/ldap/session_expiry.c
+++ b/source4/torture/ldap/session_expiry.c
@@ -55,7 +55,7 @@ bool torture_ldap_session_expiry(struct torture_context *torture)
 		torture, url!=NULL, ret, fail, "talloc_asprintf failed");
 
 	cli_credentials_set_kerberos_state(
-		credentials, CRED_MUST_USE_KERBEROS);
+		credentials, CRED_USE_KERBEROS_REQUIRED);
 
 	ok = lpcfg_set_option(
 		torture->lp_ctx, "gensec_gssapi:requested_life_time=4");
diff --git a/source4/torture/raw/session.c b/source4/torture/raw/session.c
index 0c460ae3069..e246d25e9fb 100644
--- a/source4/torture/raw/session.c
+++ b/source4/torture/raw/session.c
@@ -245,12 +245,12 @@ static bool test_session_expire1(struct torture_context *tctx)
 
 	use_kerberos = cli_credentials_get_kerberos_state(
 				popt_get_cmdline_credentials());
-	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
+	if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
 		torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
 		torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
 	}
 
-	torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
+	torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED,
 				 "please use -k yes");
 
 	lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4");
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index fff0b1aacbd..a5755041040 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -965,8 +965,8 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture)
 	torture_assert(torture, s->join_ctx2 != NULL,
 		       "Failed to join domain with acct_flags=ACB_WSTRUST");
 
-	cli_credentials_set_kerberos_state(s->wks_creds1, CRED_DONT_USE_KERBEROS);
-	cli_credentials_set_kerberos_state(s->wks_creds2, CRED_DONT_USE_KERBEROS);
+	cli_credentials_set_kerberos_state(s->wks_creds1, CRED_USE_KERBEROS_DISABLED);
+	cli_credentials_set_kerberos_state(s->wks_creds2, CRED_USE_KERBEROS_DISABLED);
 
 	for (i=0; i < s->nprocs; i++) {
 		struct cli_credentials *wks = s->wks_creds1;
diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c
index 07c6faebb15..701dfc10a07 100644
--- a/source4/torture/smb2/session.c
+++ b/source4/torture/smb2/session.c
@@ -956,7 +956,7 @@ bool test_session_reauth6(struct torture_context *tctx, struct smb2_tree *tree)
 
 	krb_state = cli_credentials_get_kerberos_state(
 			popt_get_cmdline_credentials());
-	if (krb_state == CRED_MUST_USE_KERBEROS) {
+	if (krb_state == CRED_USE_KERBEROS_REQUIRED) {
 		torture_skip(tctx,
 			     "Can't test failing session setup with kerberos.");
 	}
@@ -1064,12 +1064,12 @@ static bool test_session_expire1i(struct torture_context *tctx,
 	size_t i;
 
 	use_kerberos = cli_credentials_get_kerberos_state(credentials);
-	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
+	if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
 		torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
 		torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
 	}
 
-	torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
+	torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED,
 				 "please use -k yes");
 
 	cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
@@ -1250,12 +1250,12 @@ static bool test_session_expire2i(struct torture_context *tctx,
 	struct smb2_notify ntf2;
 
 	use_kerberos = cli_credentials_get_kerberos_state(credentials);
-	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
+	if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
 		torture_warning(tctx, "smb2.session.expire2 requires -k yes!");
 		torture_skip(tctx, "smb2.session.expire2 requires -k yes!");
 	}
 
-	torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS,
+	torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED,
 				 "please use -k yes");
 
 	cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED);
@@ -1612,7 +1612,7 @@ static bool test_session_expire_disconnect(struct torture_context *tctx)
 	bool connected;
 
 	use_kerberos = cli_credentials_get_kerberos_state(credentials);
-	if (use_kerberos != CRED_MUST_USE_KERBEROS) {
+	if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) {
 		torture_warning(tctx, "smb2.session.expire1 requires -k yes!");
 		torture_skip(tctx, "smb2.session.expire1 requires -k yes!");
 	}
-- 
2.29.2


From dd116a6a1b334431981b786c103503d9e2998247 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 1 Sep 2020 12:32:28 +0200
Subject: [PATCH 087/104] auth:creds:tests: Migrate test to a cmocka unit test

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 1a92994a9513f5e73d30604a1dc217ddeb1ac8d5)
---
 auth/credentials/tests/test_creds.c | 221 ++++++++++++++++++++++++++++
 auth/credentials/wscript_build      |   6 +
 selftest/tests.py                   |   2 +
 source4/torture/local/local.c       |   1 -
 source4/torture/local/wscript_build |   2 +-
 5 files changed, 230 insertions(+), 2 deletions(-)
 create mode 100644 auth/credentials/tests/test_creds.c

diff --git a/auth/credentials/tests/test_creds.c b/auth/credentials/tests/test_creds.c
new file mode 100644
index 00000000000..d2d3d30d73d
--- /dev/null
+++ b/auth/credentials/tests/test_creds.c
@@ -0,0 +1,221 @@
+/*
+ * Unix SMB/CIFS implementation.
+ *
+ * Copyright (C) 2018-2019 Andreas Schneider <asn@samba.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "lib/replace/replace.h"
+#include "auth/credentials/credentials.c"
+
+static int setup_talloc_context(void **state)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	*state = frame;
+	return 0;
+}
+
+static int teardown_talloc_context(void **state)
+{
+	TALLOC_CTX *frame = *state;
+	TALLOC_FREE(frame);
+	return 0;
+}
+
+static void torture_creds_init(void **state)
+{
+	TALLOC_CTX *mem_ctx = *state;
+	struct cli_credentials *creds = NULL;
+	const char *username = NULL;
+	const char *domain = NULL;
+	const char *password = NULL;
+	bool ok;
+
+	creds = cli_credentials_init(mem_ctx);
+	assert_non_null(creds);
+	assert_null(creds->username);
+	assert_int_equal(creds->username_obtained, CRED_UNINITIALISED);
+
+	domain = cli_credentials_get_domain(creds);
+	assert_null(domain);
+	ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED);
+	assert_true(ok);
+	assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
+	domain = cli_credentials_get_domain(creds);
+	assert_string_equal(domain, "WURST");
+
+	username = cli_credentials_get_username(creds);
+	assert_null(username);
+	ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED);
+	assert_true(ok);
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+	username = cli_credentials_get_username(creds);
+	assert_string_equal(username, "brot");
+
+	password = cli_credentials_get_password(creds);
+	assert_null(password);
+	ok = cli_credentials_set_password(creds, "SECRET", CRED_SPECIFIED);
+	assert_true(ok);
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+	password = cli_credentials_get_password(creds);
+	assert_string_equal(password, "SECRET");
+}
+
+static void torture_creds_init_anonymous(void **state)
+{
+	TALLOC_CTX *mem_ctx = *state;
+	struct cli_credentials *creds = NULL;
+
+	creds = cli_credentials_init_anon(mem_ctx);
+	assert_non_null(creds);
+
+	assert_string_equal(creds->domain, "");
+	assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->username, "");
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+
+	assert_null(creds->password);
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+}
+
+static void torture_creds_guess(void **state)
+{
+	TALLOC_CTX *mem_ctx = *state;
+	struct cli_credentials *creds = NULL;
+	const char *env_user = getenv("USER");
+
+	creds = cli_credentials_init(mem_ctx);
+	assert_non_null(creds);
+
+	setenv("PASSWD", "SECRET", 1);
+	cli_credentials_guess(creds, NULL);
+
+	assert_string_equal(creds->username, env_user);
+	assert_int_equal(creds->username_obtained, CRED_GUESS_ENV);
+
+	assert_string_equal(creds->password, "SECRET");
+	assert_int_equal(creds->password_obtained, CRED_GUESS_ENV);
+	unsetenv("PASSWD");
+}
+
+static void torture_creds_anon_guess(void **state)
+{
+	TALLOC_CTX *mem_ctx = *state;
+	struct cli_credentials *creds = NULL;
+
+	creds = cli_credentials_init_anon(mem_ctx);
+	assert_non_null(creds);
+
+	setenv("PASSWD", "SECRET", 1);
+	cli_credentials_guess(creds, NULL);
+
+	assert_string_equal(creds->username, "");
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+
+	assert_null(creds->password);
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+	unsetenv("PASSWD");
+}
+
+static void torture_creds_parse_string(void **state)
+{
+	TALLOC_CTX *mem_ctx = *state;
+	struct cli_credentials *creds = NULL;
+
+	creds = cli_credentials_init(mem_ctx);
+	assert_non_null(creds);
+
+	/* Anonymous */
+	cli_credentials_parse_string(creds, "%", CRED_SPECIFIED);
+
+	assert_string_equal(creds->domain, "");
+	assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->username, "");
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+
+	assert_null(creds->password);
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+
+	/* Username + password */
+	cli_credentials_parse_string(creds, "wurst%BROT", CRED_SPECIFIED);
+
+	assert_string_equal(creds->domain, "");
+	assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->username, "wurst");
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->password, "BROT");
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+
+	/* Domain + username + password */
+	cli_credentials_parse_string(creds, "XXL\\wurst%BROT", CRED_SPECIFIED);
+
+	assert_string_equal(creds->domain, "XXL");
+	assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->username, "wurst");
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->password, "BROT");
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+
+	/* Principal */
+	cli_credentials_parse_string(creds, "wurst@brot.realm", CRED_SPECIFIED);
+
+	assert_string_equal(creds->domain, "");
+	assert_int_equal(creds->domain_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->username, "wurst@brot.realm");
+	assert_int_equal(creds->username_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->principal, "wurst@brot.realm");
+	assert_int_equal(creds->principal_obtained, CRED_SPECIFIED);
+
+	assert_string_equal(creds->password, "BROT");
+	assert_int_equal(creds->password_obtained, CRED_SPECIFIED);
+}
+
+int main(int argc, char *argv[])
+{
+	int rc;
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(torture_creds_init),
+		cmocka_unit_test(torture_creds_init_anonymous),
+		cmocka_unit_test(torture_creds_guess),
+		cmocka_unit_test(torture_creds_anon_guess),
+		cmocka_unit_test(torture_creds_parse_string),
+	};
+
+	if (argc == 2) {
+		cmocka_set_test_filter(argv[1]);
+	}
+	cmocka_set_message_output(CM_OUTPUT_SUBUNIT);
+
+	rc = cmocka_run_group_tests(tests,
+				    setup_talloc_context,
+				    teardown_talloc_context);
+
+	return rc;
+}
diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build
index ad16b7d8008..46111164b36 100644
--- a/auth/credentials/wscript_build
+++ b/auth/credentials/wscript_build
@@ -31,3 +31,9 @@ bld.SAMBA_PYTHON('pycredentials',
     public_deps='samba-credentials cmdline-credentials %s %s CREDENTIALS_KRB5 CREDENTIALS_SECRETS' % (pytalloc_util, pyparam_util),
     realname='samba/credentials.so'
 )
+
+bld.SAMBA_BINARY('test_creds',
+                 source='tests/test_creds.c',
+                 deps='cmocka samba-credentials',
+                 local_include=False,
+                 for_selftest=True)
diff --git a/selftest/tests.py b/selftest/tests.py
index 86cab3f8046..4a968cdbe8a 100644
--- a/selftest/tests.py
+++ b/selftest/tests.py
@@ -418,3 +418,5 @@ plantestsuite("samba.unittests.test_oLschema2ldif", "none",
 if with_elasticsearch_backend:
     plantestsuite("samba.unittests.mdsparser_es", "none",
                   [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration])
+plantestsuite("samba.unittests.credentials", "none",
+              [os.path.join(bindir(), "default/auth/credentials/test_creds")])
diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c
index a3186788524..d19b55e9502 100644
--- a/source4/torture/local/local.c
+++ b/source4/torture/local/local.c
@@ -70,7 +70,6 @@
 	torture_local_tevent_req,
 	torture_local_torture,
 	torture_local_dbspeed, 
-	torture_local_credentials,
 	torture_ldb,
 	torture_dsdb_dn,
 	torture_dsdb_syntax,
diff --git a/source4/torture/local/wscript_build b/source4/torture/local/wscript_build
index 38b6c8f4b6e..f0ab0357986 100644
--- a/source4/torture/local/wscript_build
+++ b/source4/torture/local/wscript_build
@@ -16,7 +16,7 @@ TORTURE_LOCAL_SOURCE = '''../../../lib/util/charset/tests/iconv.c
 	../../libcli/security/tests/sddl.c ../../../lib/tdr/testsuite.c
 	../../../lib/tevent/testsuite.c ../../param/tests/share.c
         ../../../lib/tevent/test_req.c
-	../../param/tests/loadparm.c ../../../auth/credentials/tests/simple.c local.c
+	../../param/tests/loadparm.c local.c
 	dbspeed.c torture.c ../ldb/ldb.c ../../dsdb/common/tests/dsdb_dn.c
 	../../dsdb/schema/tests/schema_syntax.c
 	../../../lib/util/tests/anonymous_shared.c
-- 
2.29.2


From 48c31546ad4c2a072497e3ce9eff37ef37bc81c8 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:09:05 +0200
Subject: [PATCH 088/104] Add smb2cli_session_get_encryption_cipher()

When 'session->smb2->should_encrypt' is true, the client MUST encrypt
all transport messages (see also MS-SMB2 3.2.4.1.8).

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit f0f8de9d4a4e05445e427f00bb10eb34e1110a97)
---
 libcli/smb/smbXcli_base.c | 13 +++++++++++++
 libcli/smb/smbXcli_base.h |  1 +
 2 files changed, 14 insertions(+)

diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 7d2da4b9ebc..471319a32f1 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -6436,6 +6436,19 @@ NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session)
 	return NT_STATUS_OK;
 }
 
+uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session)
+{
+	if (session->conn->protocol < PROTOCOL_SMB2_24) {
+		return 0;
+	}
+
+	if (!session->smb2->should_encrypt) {
+		return 0;
+	}
+
+	return session->conn->smb2.server.cipher;
+}
+
 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx)
 {
 	struct smbXcli_tcon *tcon;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 2afc7165cd9..db5f5d58799 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -518,6 +518,7 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session,
 					 const DATA_BLOB channel_key,
 					 const struct iovec *recv_iov);
 NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session);
+uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session);
 
 struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx);
 struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx,
-- 
2.29.2


From 25a7d3534f7e3798cdf2432de62ed62f9e11547b Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:18:21 +0200
Subject: [PATCH 089/104] Add dcerpc_transport_encrypted()

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 339bfcd67af2675d10287946d8f5dabba1022d57)
---
 source4/librpc/rpc/dcerpc.h      |  2 ++
 source4/librpc/rpc/dcerpc_smb.c  | 11 +++++++++++
 source4/librpc/rpc/dcerpc_util.c | 13 +++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index 6b0b841d64d..57124f10778 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -87,6 +87,7 @@ struct dcecli_connection {
 	struct dcerpc_transport {
 		enum dcerpc_transport_t transport;
 		void *private_data;
+		bool encrypted;
 
 		struct tstream_context *stream;
 		/** to serialize write events */
@@ -181,6 +182,7 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p,
 			       const struct ndr_interface_table *table);
 NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
 				  DATA_BLOB *session_key);
+bool dcerpc_transport_encrypted(struct dcerpc_pipe *p);
 struct composite_context;
 NTSTATUS dcerpc_secondary_connection_recv(struct composite_context *c,
 					  struct dcerpc_pipe **p2);
diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c
index b20b154a1cb..101ed64f0cd 100644
--- a/source4/librpc/rpc/dcerpc_smb.c
+++ b/source4/librpc/rpc/dcerpc_smb.c
@@ -145,6 +145,7 @@ static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq)
 		struct dcerpc_pipe_open_smb_state);
 	struct composite_context *ctx = state->ctx;
 	struct dcecli_connection *c = state->c;
+	uint16_t enc_cipher;
 
 	ctx->status = tstream_smbXcli_np_open_recv(subreq,
 						   state->smb,
@@ -173,6 +174,16 @@ static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq)
 	/* Over-ride the default session key with the SMB session key */
 	c->security_state.session_key = smb_session_key;
 
+	enc_cipher = smb2cli_session_get_encryption_cipher(state->smb->session);
+	switch (enc_cipher) {
+	case SMB2_ENCRYPTION_AES128_CCM:
+	case SMB2_ENCRYPTION_AES128_GCM:
+		c->transport.encrypted = true;
+		break;
+	default:
+		c->transport.encrypted = false;
+	}
+
 	c->transport.private_data = talloc_move(c, &state->smb);
 
 	composite_done(ctx);
diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c
index bd79a072bc8..6ea27a8d9a3 100644
--- a/source4/librpc/rpc/dcerpc_util.c
+++ b/source4/librpc/rpc/dcerpc_util.c
@@ -743,6 +743,19 @@ _PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p,
 	return NT_STATUS_OK;
 }
 
+_PUBLIC_ bool dcerpc_transport_encrypted(struct dcerpc_pipe *p)
+{
+	if (p == NULL) {
+		return false;
+	}
+
+	if (p->conn == NULL) {
+		return false;
+	}
+
+	return p->conn->transport.encrypted;
+}
+
 /*
   create a secondary context from a primary connection
 
-- 
2.29.2


From a0b8ea04d7030d2cb97d6ccea9d28072d6e3dbda Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:35:01 +0200
Subject: [PATCH 090/104] Add py binding for dcerpc_transport_encrypted

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit eba91f0dfa8e3267689b4076302e257f4cecd63b)
---
 source4/librpc/rpc/pyrpc.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c
index be914ed5f14..309a6d72e26 100644
--- a/source4/librpc/rpc/pyrpc.c
+++ b/source4/librpc/rpc/pyrpc.c
@@ -293,11 +293,25 @@ static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwar
 	return ret;
 }
 
+static PyObject *py_iface_transport_encrypted(PyObject *self)
+{
+	dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
+
+	if (dcerpc_transport_encrypted(iface->pipe)) {
+		Py_RETURN_TRUE;
+	}
+
+	Py_RETURN_FALSE;
+}
+
 static PyMethodDef dcerpc_interface_methods[] = {
 	{ "request", PY_DISCARD_FUNC_SIG(PyCFunction, py_iface_request),
 		METH_VARARGS|METH_KEYWORDS,
 		"S.request(opnum, data, object=None) -> data\n"
 		"Make a raw request" },
+	{ "transport_encrypted", PY_DISCARD_FUNC_SIG(PyCFunction, py_iface_transport_encrypted),
+		METH_NOARGS,
+		"Check if the DCE transport is encrypted" },
 	{ NULL, NULL, 0, NULL },
 };
 
-- 
2.29.2


From ff38da1d43f7ec3312a90fb8c53f977c9466e199 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:44:08 +0200
Subject: [PATCH 091/104] selftest: add a test for py dce transport_encrypted

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit a77551bea969ce73a3dc27384d94b4126bef04f7)
---
 python/samba/tests/dcerpc/binding.py | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/python/samba/tests/dcerpc/binding.py b/python/samba/tests/dcerpc/binding.py
index 8e0d6a5ef0a..24e4ac77d89 100644
--- a/python/samba/tests/dcerpc/binding.py
+++ b/python/samba/tests/dcerpc/binding.py
@@ -22,7 +22,7 @@ import samba.tests
 from samba.tests import RpcInterfaceTestCase, TestCase
 from samba.dcerpc import lsa
 import samba.dcerpc.security as security
-from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED
+from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED, SMB_ENCRYPTION_OFF
 from samba import NTSTATUSError
 
 class RpcBindingTests(RpcInterfaceTestCase):
@@ -40,6 +40,26 @@ class RpcBindingTests(RpcInterfaceTestCase):
         c.set_password(password)
         return c
 
+    def test_smb3_dcerpc_no_encryption(self):
+        creds = self.get_user_creds()
+        creds.set_smb_encryption(SMB_ENCRYPTION_OFF)
+
+        lp = self.get_loadparm()
+        lp.set('client ipc max protocol', 'SMB3')
+        lp.set('client ipc min protocol', 'SMB3')
+
+        binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')))
+        lsa_conn = lsa.lsarpc(binding_string, lp, creds)
+        self.assertFalse(lsa_conn.transport_encrypted())
+
+        objectAttr = lsa.ObjectAttribute()
+        objectAttr.sec_qos = lsa.QosInfo()
+
+        pol_handle = lsa_conn.OpenPolicy2('',
+                                          objectAttr,
+                                          security.SEC_FLAG_MAXIMUM_ALLOWED)
+        self.assertIsNotNone(pol_handle)
+
     def test_smb3_dcerpc_encryption(self):
         creds = self.get_user_creds()
         creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
@@ -50,6 +70,7 @@ class RpcBindingTests(RpcInterfaceTestCase):
 
         binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')))
         lsa_conn = lsa.lsarpc(binding_string, lp, creds)
+        self.assertTrue(lsa_conn.transport_encrypted())
 
         objectAttr = lsa.ObjectAttribute()
         objectAttr.sec_qos = lsa.QosInfo()
-- 
2.29.2


From 5ffb0a0d9093bba2c4630d89512f623a35122f8e Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:47:12 +0200
Subject: [PATCH 092/104] Add CreateTrustedDomainRelax wrapper for fips mode

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit c2644032b49b4160517a7c73634cebc54a76f827)
---
 python/samba/trust_utils.py | 62 +++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 python/samba/trust_utils.py

diff --git a/python/samba/trust_utils.py b/python/samba/trust_utils.py
new file mode 100644
index 00000000000..b4df0fa5bb8
--- /dev/null
+++ b/python/samba/trust_utils.py
@@ -0,0 +1,62 @@
+# trust utils
+#
+# Copyright Isaac Boukris 2020
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+
+from samba.dcerpc import lsa, drsblobs
+from samba.ndr import ndr_pack
+from samba import arcfour_encrypt, string_to_byte_array
+import random
+from samba import crypto
+
+def CreateTrustedDomainRelax(lsaconn, policy, trust_info, mask, in_blob, out_blob):
+
+    def generate_AuthInfoInternal(session_key, incoming=None, outgoing=None):
+        confounder = [0] * 512
+        for i in range(len(confounder)):
+            confounder[i] = random.randint(0, 255)
+
+        trustpass = drsblobs.trustDomainPasswords()
+
+        trustpass.confounder = confounder
+        trustpass.outgoing = outgoing
+        trustpass.incoming = incoming
+
+        trustpass_blob = ndr_pack(trustpass)
+
+        encrypted_trustpass = arcfour_encrypt(session_key, trustpass_blob)
+
+        auth_blob = lsa.DATA_BUF2()
+        auth_blob.size = len(encrypted_trustpass)
+        auth_blob.data = string_to_byte_array(encrypted_trustpass)
+
+        auth_info = lsa.TrustDomainInfoAuthInfoInternal()
+        auth_info.auth_blob = auth_blob
+
+        return auth_info
+
+    session_key = lsaconn.session_key
+
+    try:
+        if lsaconn.transport_encrypted():
+            crypto.set_relax_mode()
+        auth_info = generate_AuthInfoInternal(session_key,
+                                              incoming=in_blob,
+                                              outgoing=out_blob)
+    finally:
+        crypto.set_strict_mode()
+
+    return lsaconn.CreateTrustedDomainEx2(policy, trust_info, auth_info, mask)
-- 
2.29.2


From d980bb1444e318825457ead9bdbce1c9353ccc66 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 20 Aug 2020 12:49:17 +0200
Subject: [PATCH 093/104] Use the new CreateTrustedDomainRelax()

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit baf4e2930ee13b47c23c63c7e945fdc4444f0c69)
---
 python/samba/netcmd/domain.py | 57 ++++++++---------------------------
 1 file changed, 13 insertions(+), 44 deletions(-)

diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py
index 1d12c362911..93a3258d28d 100644
--- a/python/samba/netcmd/domain.py
+++ b/python/samba/netcmd/domain.py
@@ -102,6 +102,7 @@ from samba.netcmd.domain_backup import cmd_domain_backup
 
 from samba.compat import binary_type
 from samba.compat import get_string
+from samba.trust_utils import CreateTrustedDomainRelax
 
 string_version_to_constant = {
     "2008_R2": DS_DOMAIN_FUNCTION_2008_R2,
@@ -2528,54 +2529,20 @@ class cmd_domain_trust_create(DomainTrustCommand):
 
             return blob
 
-        def generate_AuthInfoInternal(session_key, incoming=None, outgoing=None):
-            confounder = [0] * 512
-            for i in range(len(confounder)):
-                confounder[i] = random.randint(0, 255)
-
-            trustpass = drsblobs.trustDomainPasswords()
-
-            trustpass.confounder = confounder
-            trustpass.outgoing = outgoing
-            trustpass.incoming = incoming
-
-            trustpass_blob = ndr_pack(trustpass)
-
-            encrypted_trustpass = arcfour_encrypt(session_key, trustpass_blob)
-
-            auth_blob = lsa.DATA_BUF2()
-            auth_blob.size = len(encrypted_trustpass)
-            auth_blob.data = string_to_byte_array(encrypted_trustpass)
-
-            auth_info = lsa.TrustDomainInfoAuthInfoInternal()
-            auth_info.auth_blob = auth_blob
-
-            return auth_info
-
         update_time = samba.current_unix_time()
         incoming_blob = generate_AuthInOutBlob(incoming_secret, update_time)
         outgoing_blob = generate_AuthInOutBlob(outgoing_secret, update_time)
 
-        local_tdo_handle = None
-        remote_tdo_handle = None
-
-        local_auth_info = generate_AuthInfoInternal(local_lsa.session_key,
-                                                    incoming=incoming_blob,
-                                                    outgoing=outgoing_blob)
-        if remote_trust_info:
-            remote_auth_info = generate_AuthInfoInternal(remote_lsa.session_key,
-                                                         incoming=outgoing_blob,
-                                                         outgoing=incoming_blob)
-
         try:
             if remote_trust_info:
                 self.outf.write("Creating remote TDO.\n")
                 current_request = {"location": "remote", "name": "CreateTrustedDomainEx2"}
-                remote_tdo_handle = \
-                    remote_lsa.CreateTrustedDomainEx2(remote_policy,
-                                                      remote_trust_info,
-                                                      remote_auth_info,
-                                                      lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS)
+                remote_tdo_handle = CreateTrustedDomainRelax(remote_lsa,
+                                                             remote_policy,
+                                                             remote_trust_info,
+                                                             lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS,
+                                                             outgoing_blob,
+                                                             incoming_blob)
                 self.outf.write("Remote TDO created.\n")
                 if enc_types:
                     self.outf.write("Setting supported encryption types on remote TDO.\n")
@@ -2586,10 +2553,12 @@ class cmd_domain_trust_create(DomainTrustCommand):
 
             self.outf.write("Creating local TDO.\n")
             current_request = {"location": "local", "name": "CreateTrustedDomainEx2"}
-            local_tdo_handle = local_lsa.CreateTrustedDomainEx2(local_policy,
-                                                                local_trust_info,
-                                                                local_auth_info,
-                                                                lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS)
+            local_tdo_handle = CreateTrustedDomainRelax(local_lsa,
+                                                        local_policy,
+                                                        local_trust_info,
+                                                        lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS,
+                                                        incoming_blob,
+                                                        outgoing_blob)
             self.outf.write("Local TDO created\n")
             if enc_types:
                 self.outf.write("Setting supported encryption types on local TDO.\n")
-- 
2.29.2


From e06d01fe3370501ab45d01c5511aa0b5de9d854e Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Tue, 1 Sep 2020 20:14:29 +0300
Subject: [PATCH 094/104] selftest: add a test for the CreateTrustedDomainRelax
 wrapper

Originally copied from 'source4/scripting/devel/createtrust'
(had to drop the TRUST_AUTH_TYPE_VERSION part though, as it
fails against samba DC).

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit cfaad16ff632df83a881fe5d8ec498bab102c9c9)
---
 python/samba/tests/dcerpc/createtrustrelax.py | 131 ++++++++++++++++++
 selftest/knownfail.d/createtrustrelax_server  |   1 +
 source4/selftest/tests.py                     |   4 +
 3 files changed, 136 insertions(+)
 create mode 100644 python/samba/tests/dcerpc/createtrustrelax.py
 create mode 100644 selftest/knownfail.d/createtrustrelax_server

diff --git a/python/samba/tests/dcerpc/createtrustrelax.py b/python/samba/tests/dcerpc/createtrustrelax.py
new file mode 100644
index 00000000000..48beb0f9680
--- /dev/null
+++ b/python/samba/tests/dcerpc/createtrustrelax.py
@@ -0,0 +1,131 @@
+# Unix SMB/CIFS implementation.
+#
+# Copyright (C) Andrew Bartlett 2011
+# Copyright (C) Isaac Boukris 2020
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""Tests for the CreateTrustedDomainRelax wrapper"""
+
+import os
+import samba
+from samba.tests import TestCase
+from samba.dcerpc import lsa, security, drsblobs
+from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED, SMB_ENCRYPTION_OFF
+from samba.trust_utils import CreateTrustedDomainRelax
+
+class CreateTrustedDomainRelaxTest(TestCase):
+    def setUp(self):
+        super(CreateTrustedDomainRelaxTest, self).setUp()
+
+    def get_user_creds(self):
+        c = Credentials()
+        c.guess()
+        domain = samba.tests.env_get_var_value('DOMAIN')
+        username = samba.tests.env_get_var_value('USERNAME')
+        password = samba.tests.env_get_var_value('PASSWORD')
+        c.set_domain(domain)
+        c.set_username(username)
+        c.set_password(password)
+        return c
+
+    def _create_trust_relax(self, smbencrypt=True):
+        creds = self.get_user_creds()
+
+        if smbencrypt:
+            creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
+        else:
+            creds.set_smb_encryption(SMB_ENCRYPTION_OFF)
+
+        lp = self.get_loadparm()
+
+        binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER')))
+        lsa_conn = lsa.lsarpc(binding_string, lp, creds)
+
+        if smbencrypt:
+            self.assertTrue(lsa_conn.transport_encrypted())
+        else:
+            self.assertFalse(lsa_conn.transport_encrypted())
+
+        objectAttr = lsa.ObjectAttribute()
+        objectAttr.sec_qos = lsa.QosInfo()
+
+        pol_handle = lsa_conn.OpenPolicy2('',
+                                          objectAttr,
+                                          security.SEC_FLAG_MAXIMUM_ALLOWED)
+        self.assertIsNotNone(pol_handle)
+
+        name = lsa.String()
+        name.string = "tests.samba.example.com"
+        try:
+            info = lsa_conn.QueryTrustedDomainInfoByName(pol_handle, name,
+                                                         lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
+
+            lsa_conn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)
+        except RuntimeError:
+            pass
+
+        info = lsa.TrustDomainInfoInfoEx()
+        info.domain_name.string = name.string
+        info.netbios_name.string = "createtrustrelax"
+        info.sid = security.dom_sid("S-1-5-21-538490383-3740119673-95748416")
+        info.trust_direction = lsa.LSA_TRUST_DIRECTION_INBOUND | lsa.LSA_TRUST_DIRECTION_OUTBOUND
+        info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL
+        info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE
+
+        password_blob = samba.string_to_byte_array("password".encode('utf-16-le'))
+
+        clear_value = drsblobs.AuthInfoClear()
+        clear_value.size = len(password_blob)
+        clear_value.password = password_blob
+
+        clear_authentication_information = drsblobs.AuthenticationInformation()
+        clear_authentication_information.LastUpdateTime = 0
+        clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
+        clear_authentication_information.AuthInfo = clear_value
+
+        authentication_information_array = drsblobs.AuthenticationInformationArray()
+        authentication_information_array.count = 1
+        authentication_information_array.array = [clear_authentication_information]
+
+        outgoing = drsblobs.trustAuthInOutBlob()
+        outgoing.count = 1
+        outgoing.current = authentication_information_array
+
+        trustdom_handle = None
+        try:
+            trustdom_handle = CreateTrustedDomainRelax(lsa_conn,
+                                                       pol_handle,
+                                                       info,
+                                                       security.SEC_STD_DELETE,
+                                                       outgoing,
+                                                       outgoing)
+        except samba.NTSTATUSError as nt:
+            raise AssertionError(nt)
+        except OSError as e:
+            if smbencrypt:
+                raise AssertionError(e)
+
+        if smbencrypt:
+            self.assertIsNotNone(trustdom_handle)
+            lsa_conn.DeleteTrustedDomain(pol_handle, info.sid)
+        else:
+            self.assertIsNone(trustdom_handle)
+
+    def test_create_trust_relax_encrypt(self):
+        self._create_trust_relax(True)
+
+    def test_create_trust_relax_no_enc(self):
+        self._create_trust_relax(False)
diff --git a/selftest/knownfail.d/createtrustrelax_server b/selftest/knownfail.d/createtrustrelax_server
new file mode 100644
index 00000000000..80effda8343
--- /dev/null
+++ b/selftest/knownfail.d/createtrustrelax_server
@@ -0,0 +1 @@
+^samba.tests.dcerpc.createtrustrelax.samba.tests.dcerpc.createtrustrelax.CreateTrustedDomainRelaxTest.test_create_trust_relax_encrypt\(ad_dc_fips\)
diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index 3a903a7eee0..96f51b68cfc 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -704,6 +704,10 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex
         name = module
     plantestsuite_loadlist(name, env, args)
 
+if have_gnutls_crypto_policies:
+    planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.createtrustrelax", environ={'GNUTLS_FORCE_FIPS_MODE':'1'})
+    planoldpythontestsuite("ad_dc_fips", "samba.tests.dcerpc.createtrustrelax", environ={'GNUTLS_FORCE_FIPS_MODE':'1'})
+
 # Run complex search expressions test once for each database backend.
 # Right now ad_dc has mdb and ad_dc_ntvfs has tdb
 mdb_testenv = "ad_dc"
-- 
2.29.2


From 93b792d5d0dcf96833e32958aeb3877f74125f07 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Thu, 5 Nov 2020 15:38:19 +0200
Subject: [PATCH 095/104] Remove source4/scripting/devel/createtrust script

We now have the 'samba-tool domain trust' command.

Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>

Autobuild-User(master): Isaac Boukris <iboukris@samba.org>
Autobuild-Date(master): Fri Nov  6 11:25:02 UTC 2020 on sn-devel-184

(cherry picked from commit 604153525afc892f57a1df710c41ffca275b0dd3)
---
 source4/scripting/devel/createtrust | 125 ----------------------------
 1 file changed, 125 deletions(-)
 delete mode 100755 source4/scripting/devel/createtrust

diff --git a/source4/scripting/devel/createtrust b/source4/scripting/devel/createtrust
deleted file mode 100755
index 26b0d0dcb68..00000000000
--- a/source4/scripting/devel/createtrust
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python3
-
-# create a domain trust
-
-import sys
-from optparse import OptionParser
-
-sys.path.insert(0, "bin/python")
-
-import samba
-import samba.getopt as options
-from samba.dcerpc import lsa, security, drsblobs
-from samba.ndr import ndr_pack
-from samba import arcfour_encrypt, string_to_byte_array
-import random
-
-########### main code ###########
-if __name__ == "__main__":
-    parser = OptionParser("createtrust [options] server")
-    sambaopts = options.SambaOptions(parser)
-    credopts = options.CredentialsOptionsDouble(parser)
-    parser.add_option_group(credopts)
-
-    (opts, args) = parser.parse_args()
-
-    lp = sambaopts.get_loadparm()
-    creds = credopts.get_credentials(lp)
-
-    if len(args) != 1:
-        parser.error("You must supply a server")
-
-    if not creds.authentication_requested():
-        parser.error("You must supply credentials")
-
-    server = args[0]
-
-    binding_str = "ncacn_np:%s[print]" % server
-
-    lsaconn = lsa.lsarpc(binding_str, lp, creds)
-
-    objectAttr = lsa.ObjectAttribute()
-    objectAttr.sec_qos = lsa.QosInfo()
-
-    pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'),
-                                     objectAttr, security.SEC_FLAG_MAXIMUM_ALLOWED)
-
-    name = lsa.String()
-    name.string = "sub2.win2k3.obed.home.abartlet.net"
-    try:
-        info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)
-
-        lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)
-    except RuntimeError:
-        pass
-
-    info = lsa.TrustDomainInfoInfoEx()
-    info.domain_name.string = "sub2.win2k3.obed.home.abartlet.net"
-    info.netbios_name.string = "sub2"
-    info.sid = security.dom_sid("S-1-5-21-538090388-3760119675-95745416")
-    info.trust_direction = lsa.LSA_TRUST_DIRECTION_INBOUND | lsa.LSA_TRUST_DIRECTION_OUTBOUND
-    info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL
-    info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_WITHIN_FOREST
-
-    password_blob = string_to_byte_array("password".encode('utf-16-le'))
-
-    clear_value = drsblobs.AuthInfoClear()
-    clear_value.size = len(password_blob)
-    clear_value.password = password_blob
-
-    clear_authentication_information = drsblobs.AuthenticationInformation()
-    clear_authentication_information.LastUpdateTime = 0
-    clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR
-    clear_authentication_information.AuthInfo = clear_value
-
-    version_value = drsblobs.AuthInfoVersion()
-    version_value.version = 1
-
-    version = drsblobs.AuthenticationInformation()
-    version.LastUpdateTime = 0
-    version.AuthType = lsa.TRUST_AUTH_TYPE_VERSION
-    version.AuthInfo = version_value
-
-    authentication_information_array = drsblobs.AuthenticationInformationArray()
-    authentication_information_array.count = 2
-    authentication_information_array.array = [clear_authentication_information, version]
-
-    outgoing = drsblobs.trustAuthInOutBlob()
-    outgoing.count = 1
-    outgoing.current = authentication_information_array
-
-    trustpass = drsblobs.trustDomainPasswords()
-    confounder = [3] * 512
-
-    for i in range(512):
-        confounder[i] = random.randint(0, 255)
-
-    trustpass.confounder = confounder
-
-#    print "confounder: ", trustpass.confounder
-
-    trustpass.outgoing = outgoing
-    trustpass.incoming = outgoing
-
-    trustpass_blob = ndr_pack(trustpass)
-
-#    print "trustpass_blob: ", list(trustpass_blob)
-
-    encrypted_trustpass = arcfour_encrypt(lsaconn.session_key, trustpass_blob)
-
-#    print "encrypted_trustpass: ", list(encrypted_trustpass)
-
-    auth_blob = lsa.DATA_BUF2()
-    auth_blob.size = len(encrypted_trustpass)
-    auth_blob.data = string_to_byte_array(encrypted_trustpass)
-
-    auth_info = lsa.TrustDomainInfoAuthInfoInternal()
-    auth_info.auth_blob = auth_blob
-
-
-#    print "auth_info.auth_blob.data: ", auth_info.auth_blob.data
-
-    trustdom_handle = lsaconn.CreateTrustedDomainEx2(pol_handle,
-                                                     info,
-                                                     auth_info,
-                                                     security.SEC_STD_DELETE)
-- 
2.29.2


From 4577786be36993e958b745e4953f582e3de301a1 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 6 Nov 2020 14:30:26 +0100
Subject: [PATCH 096/104] s3:rpc_server: Use gnutls_cipher_decrypt() in
 get_trustdom_auth_blob()

It doesn't matter for RC4, but just to be correct.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit 6c11e5f42ba3248c97d85c989d422b256d2465a9)
---
 source3/rpc_server/lsa/srv_lsa_nt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
index 198387424e6..e749caf2551 100644
--- a/source3/rpc_server/lsa/srv_lsa_nt.c
+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
@@ -1726,7 +1726,7 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
 		goto out;
 	}
 
-	rc = gnutls_cipher_encrypt(cipher_hnd,
+	rc = gnutls_cipher_decrypt(cipher_hnd,
 				   auth_blob->data,
 				   auth_blob->length);
 	gnutls_cipher_deinit(cipher_hnd);
-- 
2.29.2


From ad9c90d18c2efdee16535ade97d4b151e4a64c5e Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 6 Nov 2020 14:33:38 +0100
Subject: [PATCH 097/104] s4:rpc_server: Use gnutls_cipher_decrypt() in
 get_trustdom_auth_blob()

It doesn't matter for RC4, but just to be correct.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
(cherry picked from commit c93ccebdfedd60c1d19f1b1436ac30062259952a)
---
 source4/rpc_server/lsa/dcesrv_lsa.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 8333cb149b6..4bb8aaa9592 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -889,7 +889,7 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
 		goto out;
 	}
 
-	rc = gnutls_cipher_encrypt(cipher_hnd,
+	rc = gnutls_cipher_decrypt(cipher_hnd,
 				   auth_blob->data,
 				   auth_blob->length);
 	gnutls_cipher_deinit(cipher_hnd);
-- 
2.29.2


From 6c73bf8553c48e28abd09ff225cbfb8278528d0d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 20 Aug 2020 13:40:21 +0200
Subject: [PATCH 098/104] s3:rpc_server: Allow to use RC4 for creating trusts

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit 4425f2c113a4dc33a8dc609d84a92018d61b4d2e)
---
 source3/rpc_server/lsa/srv_lsa_nt.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
index e749caf2551..d6d606ddeca 100644
--- a/source3/rpc_server/lsa/srv_lsa_nt.c
+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
@@ -51,6 +51,8 @@
 #include "../libcli/lsarpc/util_lsarpc.h"
 #include "lsa.h"
 #include "librpc/rpc/dcesrv_core.h"
+#include "librpc/rpc/dcerpc_helper.h"
+#include "lib/param/loadparm.h"
 
 #include "lib/crypto/gnutls_helpers.h"
 #include <gnutls/gnutls.h>
@@ -1706,6 +1708,14 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
 	gnutls_datum_t my_session_key;
 	NTSTATUS status;
 	int rc;
+	bool encrypted;
+
+	encrypted =
+		dcerpc_is_transport_encrypted(p->session_info);
+	if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+	    !encrypted) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
 
 	status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1717,11 +1727,13 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
 		.size = lsession_key.length,
 	};
 
+	GNUTLS_FIPS140_SET_LAX_MODE();
 	rc = gnutls_cipher_init(&cipher_hnd,
 				GNUTLS_CIPHER_ARCFOUR_128,
 				&my_session_key,
 				NULL);
 	if (rc < 0) {
+		GNUTLS_FIPS140_SET_STRICT_MODE();
 		status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto out;
 	}
@@ -1730,6 +1742,7 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
 				   auth_blob->data,
 				   auth_blob->length);
 	gnutls_cipher_deinit(cipher_hnd);
+	GNUTLS_FIPS140_SET_STRICT_MODE();
 	if (rc < 0) {
 		status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto out;
-- 
2.29.2


From 20f0e078f2dd5681513253788216313851df428d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 20 Aug 2020 13:51:39 +0200
Subject: [PATCH 099/104] s4:rpc_server: Allow to use RC4 for creating trusts

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit c75dd1ea178325b8f65343cb5c35bb93f43a49a3)
---
 source4/rpc_server/lsa/dcesrv_lsa.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c
index 4bb8aaa9592..5b3ef71d458 100644
--- a/source4/rpc_server/lsa/dcesrv_lsa.c
+++ b/source4/rpc_server/lsa/dcesrv_lsa.c
@@ -33,6 +33,8 @@
 #include "libcli/lsarpc/util_lsarpc.h"
 #include "lib/messaging/irpc.h"
 #include "libds/common/roles.h"
+#include "lib/param/loadparm.h"
+#include "librpc/rpc/dcerpc_helper.h"
 
 #include "lib/crypto/gnutls_helpers.h"
 #include <gnutls/gnutls.h>
@@ -869,6 +871,19 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
 	gnutls_cipher_hd_t cipher_hnd = NULL;
 	gnutls_datum_t _session_key;
 	int rc;
+	struct auth_session_info *session_info =
+		dcesrv_call_session_info(dce_call);
+	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
+	bool encrypted;
+
+	encrypted =
+		dcerpc_is_transport_encrypted(session_info);
+	if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
+	    !encrypted) {
+		DBG_ERR("Transport isn't encrypted and weak crypto disallowed!\n");
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 
 	nt_status = dcesrv_transport_session_key(dce_call, &session_key);
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -880,11 +895,13 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
 		.size = session_key.length,
 	};
 
+	GNUTLS_FIPS140_SET_LAX_MODE();
 	rc = gnutls_cipher_init(&cipher_hnd,
 				GNUTLS_CIPHER_ARCFOUR_128,
 				&_session_key,
 				NULL);
 	if (rc < 0) {
+		GNUTLS_FIPS140_SET_STRICT_MODE();
 		nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto out;
 	}
@@ -893,6 +910,7 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
 				   auth_blob->data,
 				   auth_blob->length);
 	gnutls_cipher_deinit(cipher_hnd);
+	GNUTLS_FIPS140_SET_STRICT_MODE();
 	if (rc < 0) {
 		nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
 		goto out;
-- 
2.29.2


From 8c7a60700f7c7925749ccfd0f3ccb17ca47df7da Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 6 Nov 2020 10:13:48 +0100
Subject: [PATCH 100/104] sefltest: Enable the dcerpc.createtrustrelax test
 against ad_dc_fips

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Mon Nov  9 10:22:51 UTC 2020 on sn-devel-184

(cherry picked from commit b89134013041e772418c2c8bcfffe8a9ade6db91)
---
 selftest/knownfail.d/createtrustrelax_server | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 selftest/knownfail.d/createtrustrelax_server

diff --git a/selftest/knownfail.d/createtrustrelax_server b/selftest/knownfail.d/createtrustrelax_server
deleted file mode 100644
index 80effda8343..00000000000
--- a/selftest/knownfail.d/createtrustrelax_server
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.dcerpc.createtrustrelax.samba.tests.dcerpc.createtrustrelax.CreateTrustedDomainRelaxTest.test_create_trust_relax_encrypt\(ad_dc_fips\)
-- 
2.29.2


From 9db0e9602ea96849a6f854415f4cd988576cccf2 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Wed, 11 Nov 2020 13:42:06 +0100
Subject: [PATCH 101/104] s3:smbd: Fix possible null pointer dereference in
 token_contains_name()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14572

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>

Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
Autobuild-Date(master): Thu Nov 12 15:13:47 UTC 2020 on sn-devel-184

(cherry picked from commit 8036bf9717f83e83c3e4a9cf00fded42e9a5de15)
---
 source3/smbd/share_access.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c
index 57754a0f766..694c0c290e8 100644
--- a/source3/smbd/share_access.c
+++ b/source3/smbd/share_access.c
@@ -79,7 +79,7 @@ static bool token_contains_name(TALLOC_CTX *mem_ctx,
 	enum lsa_SidType type;
 
 	if (username != NULL) {
-		size_t domain_len = strlen(domain);
+		size_t domain_len = domain != NULL ? strlen(domain) : 0;
 
 		/* Check if username starts with domain name */
 		if (domain_len > 0) {
-- 
2.29.2


From b92cbd97865ea6ef49892df75c59f37e9917ddb3 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab@samba.org>
Date: Tue, 10 Nov 2020 17:35:24 +0200
Subject: [PATCH 102/104] lookup_name: allow lookup names prefixed with DNS
 forest root for FreeIPA DC

In FreeIPA deployment with active Global Catalog service, when a two-way
trust to Active Directory forest is established, Windows systems can
look up FreeIPA users and groups. When using a security tab in Windows
Explorer on AD side, a lookup over a trusted forest might come as
realm\name instead of NetBIOS domain name:

--------------------------------------------------------------------
[2020/01/13 11:12:39.859134,  1, pid=33253, effective(1732401004, 1732401004), real(1732401004, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:471(ndr_print_function_debug)
       lsa_LookupNames3: struct lsa_LookupNames3
          in: struct lsa_LookupNames3
              handle                   : *
                  handle: struct policy_handle
                      handle_type              : 0x00000000 (0)
                      uuid                     : 0000000e-0000-0000-1c5e-a750e5810000
              num_names                : 0x00000001 (1)
              names: ARRAY(1)
                  names: struct lsa_String
                      length                   : 0x001e (30)
                      size                     : 0x0020 (32)
                      string                   : *
                          string                   : 'ipa.test\admins'
              sids                     : *
                  sids: struct lsa_TransSidArray3
                      count                    : 0x00000000 (0)
                      sids                     : NULL
              level                    : LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 (6)
              count                    : *
                  count                    : 0x00000000 (0)
              lookup_options           : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES (0)
              client_revision          : LSA_CLIENT_REVISION_2 (2)
--------------------------------------------------------------------

If we are running as a DC and PASSDB supports returning domain info
(pdb_get_domain_info() returns a valid structure), check domain of the
name in lookup_name() against DNS forest name and allow the request to
be done against the primary domain. This corresponds to FreeIPA's use of
Samba as a DC. For normal domain members a realm-based lookup falls back
to a lookup over to its own domain controller with the help of winbindd.

Signed-off-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>

Autobuild-User(master): Alexander Bokovoy <ab@samba.org>
Autobuild-Date(master): Wed Nov 11 10:59:01 UTC 2020 on sn-devel-184

(cherry picked from commit 31c703766fd2b89737826fb7e9a707f0622bb8cd)
---
 source3/passdb/lookup_sid.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index 82c47b3145b..864246da56e 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -113,17 +113,36 @@ bool lookup_name(TALLOC_CTX *mem_ctx,
 		full_name, domain, name));
 	DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags));
 
-	if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) &&
-	    strequal(domain, get_global_sam_name()))
-	{
+	if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) {
+		bool check_global_sam = false;
+
+		check_global_sam = strequal(domain, get_global_sam_name());
+
+		/* If we are running on a DC that has PASSDB module with domain
+		 * information, check if DNS forest name is matching the domain
+		 * name. This is the case of FreeIPA domain controller when
+		 * trusted AD DC looks up users found in a Global Catalog of
+		 * the forest root domain. */
+		if (!check_global_sam && (IS_DC)) {
+			struct pdb_domain_info *dom_info = NULL;
+			dom_info = pdb_get_domain_info(tmp_ctx);
+
+			if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
+				check_global_sam = strequal(domain, dom_info->dns_forest);
+			}
 
-		/* It's our own domain, lookup the name in passdb */
-		if (lookup_global_sam_name(name, flags, &rid, &type)) {
-			sid_compose(&sid, get_global_sam_sid(), rid);
-			goto ok;
+			TALLOC_FREE(dom_info);
+		}
+
+		if (check_global_sam) {
+			/* It's our own domain, lookup the name in passdb */
+			if (lookup_global_sam_name(name, flags, &rid, &type)) {
+				sid_compose(&sid, get_global_sam_sid(), rid);
+				goto ok;
+			}
+			TALLOC_FREE(tmp_ctx);
+			return false;
 		}
-		TALLOC_FREE(tmp_ctx);
-		return false;
 	}
 
 	if ((flags & LOOKUP_NAME_BUILTIN) &&
-- 
2.29.2


From 5bf01d45325bcc6819f807620267e35841f826a3 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <ab@samba.org>
Date: Wed, 11 Nov 2020 14:42:55 +0200
Subject: [PATCH 103/104] auth_sam: use pdb_get_domain_info to look up DNS
 forest information

When Samba is used as a part of FreeIPA domain controller, Windows
clients for a trusted AD forest may try to authenticate (perform logon
operation) as a REALM\name user account.

Fix auth_sam plugins to accept DNS forest name if we are running on a DC
with PASSDB module providing domain information (e.g. pdb_get_domain_info()
returning non-NULL structure). Right now, only FreeIPA or Samba AD DC
PASSDB backends return this information but Samba AD DC configuration is
explicitly ignored by the two auth_sam (strict and netlogon3) modules.

Detailed logs below:

[2020/11/11 09:23:53.281296,  1, pid=42677, effective(65534, 65534), real(65534, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:482(ndr_print_function_debug)
       netr_LogonSamLogonWithFlags: struct netr_LogonSamLogonWithFlags
          in: struct netr_LogonSamLogonWithFlags
              server_name              : *
                  server_name              : '\\master.ipa.test'
              computer_name            : *
                  computer_name            : 'AD1'
              credential               : *
                  credential: struct netr_Authenticator
                      cred: struct netr_Credential
                          data                     : 529f4b087c5f6546
                      timestamp                : Wed Nov 11 09:23:55 AM 2020 UTC
              return_authenticator     : *
                  return_authenticator: struct netr_Authenticator
                      cred: struct netr_Credential
                          data                     : 204f28f622010000
                      timestamp                : Fri May  2 06:37:50 AM 1986 UTC
              logon_level              : NetlogonNetworkTransitiveInformation (6)
              logon                    : *
                  logon                    : union netr_LogonLevel(case 6)
                  network                  : *
                      network: struct netr_NetworkInfo
                          identity_info: struct netr_IdentityInfo
                              domain_name: struct lsa_String
                                  length                   : 0x0010 (16)
                                  size                     : 0x01fe (510)
                                  string                   : *
                                      string                   : 'IPA.TEST'
                              parameter_control        : 0x00002ae0 (10976)
                                     0: MSV1_0_CLEARTEXT_PASSWORD_ALLOWED
                                     0: MSV1_0_UPDATE_LOGON_STATISTICS
                                     0: MSV1_0_RETURN_USER_PARAMETERS
                                     0: MSV1_0_DONT_TRY_GUEST_ACCOUNT
                                     1: MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT
                                     1: MSV1_0_RETURN_PASSWORD_EXPIRY
                                     1: MSV1_0_USE_CLIENT_CHALLENGE
                                     0: MSV1_0_TRY_GUEST_ACCOUNT_ONLY
                                     1: MSV1_0_RETURN_PROFILE_PATH
                                     0: MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY
                                     1: MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT
                                     0: MSV1_0_DISABLE_PERSONAL_FALLBACK
                                     1: MSV1_0_ALLOW_FORCE_GUEST
                                     0: MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED
                                     0: MSV1_0_USE_DOMAIN_FOR_ROUTING_ONLY
                                     0: MSV1_0_ALLOW_MSVCHAPV2
                                     0: MSV1_0_S4U2SELF
                                     0: MSV1_0_CHECK_LOGONHOURS_FOR_S4U
                                     0: MSV1_0_SUBAUTHENTICATION_DLL_EX
                              logon_id                 : 0x0000000000884ef2 (8933106)
                              account_name: struct lsa_String
                                  length                   : 0x000e (14)
                                  size                     : 0x000e (14)
                                  string                   : *
                                      string                   : 'idmuser'
                              workstation: struct lsa_String
                                  length                   : 0x0000 (0)
                                  size                     : 0x0000 (0)
                                  string                   : *
                                      string                   : ''
                         challenge                : 417207867bd33c74
                          nt: struct netr_ChallengeResponse
                              length                   : 0x00c0 (192)
                              size                     : 0x00c0 (192)
                              data                     : *
                                  data: ARRAY(192)
  [0000] A5 24 62 6E 31 DF 69 66   9E DC 54 D6 63 4C D6 2F   .$bn1.if ..T.cL./
  [0010] 01 01 00 00 00 00 00 00   50 37 D7 60 0C B8 D6 01   ........ P7.`....
  [0020] 15 1B 38 4F 47 95 4D 62   00 00 00 00 02 00 0E 00   ..8OG.Mb ........
  [0030] 57 00 49 00 4E 00 32 00   30 00 31 00 36 00 01 00   W.I.N.2. 0.1.6...
  [0040] 06 00 41 00 44 00 31 00   04 00 18 00 77 00 69 00   ..A.D.1. ....w.i.
  [0050] 6E 00 32 00 30 00 31 00   36 00 2E 00 74 00 65 00   n.2.0.1. 6...t.e.
  [0060] 73 00 74 00 03 00 20 00   61 00 64 00 31 00 2E 00   s.t... . a.d.1...
  [0070] 77 00 69 00 6E 00 32 00   30 00 31 00 36 00 2E 00   w.i.n.2. 0.1.6...
  [0080] 74 00 65 00 73 00 74 00   05 00 18 00 77 00 69 00   t.e.s.t. ....w.i.
  [0090] 6E 00 32 00 30 00 31 00   36 00 2E 00 74 00 65 00   n.2.0.1. 6...t.e.
  [00A0] 73 00 74 00 07 00 08 00   50 37 D7 60 0C B8 D6 01   s.t..... P7.`....
  [00B0] 06 00 04 00 02 00 00 00   00 00 00 00 00 00 00 00   ........ ........
                          lm: struct netr_ChallengeResponse
                              length                   : 0x0018 (24)
                              size                     : 0x0018 (24)
                              data                     : *
                                  data                     : 000000000000000000000000000000000000000000000000
              validation_level         : 0x0006 (6)
              flags                    : *
                  flags                    : 0x00000000 (0)
                         0: NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT
                         0: NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP
                         0: NETLOGON_SAMLOGON_FLAG_RODC_TO_OTHER_DOMAIN
                         0: NETLOGON_SAMLOGON_FLAG_RODC_NTLM_REQUEST

In such case checks for a workgroup name will not match the DNS forest
name used in the username specification:

[2020/11/11 09:23:53.283055,  3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:200(auth_check_ntlm_password)
  check_ntlm_password:  Checking password for unmapped user [IPA.TEST]\[idmuser]@[] with the new password interface
[2020/11/11 09:23:53.283073,  3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:203(auth_check_ntlm_password)
  check_ntlm_password:  mapped user is: [IPA.TEST]\[idmuser]@[]
[2020/11/11 09:23:53.283082, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:213(auth_check_ntlm_password)
  check_ntlm_password: auth_context challenge created by fixed
[2020/11/11 09:23:53.283091, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:216(auth_check_ntlm_password)
  challenge is:
[2020/11/11 09:23:53.283099,  5, pid=42677, effective(65534, 65534), real(65534, 0)] ../../lib/util/util.c:678(dump_data)
  [0000] 41 72 07 86 7B D3 3C 74                             Ar..{.<t
[2020/11/11 09:23:53.283113, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth_sam.c:209(auth_sam_netlogon3_auth)
  auth_sam_netlogon3_auth: Check auth for: [IPA.TEST]\[idmuser]
[2020/11/11 09:23:53.283123,  5, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth_sam.c:234(auth_sam_netlogon3_auth)
  auth_sam_netlogon3_auth: IPA.TEST is not our domain name (DC for IPA)
[2020/11/11 09:23:53.283131, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:249(auth_check_ntlm_password)
  auth_check_ntlm_password: sam_netlogon3 had nothing to say

and overall authentication attempt will fail: auth_winbind will complain
that this domain is not a trusted one and refuse operating on it:

[2020/11/11 09:23:53.283784, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:742(process_request_send)
  process_request_send: process_request: Handling async request smbd(42677):PAM_AUTH_CRAP
[2020/11/11 09:23:53.283796,  3, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd_pam_auth_crap.c:110(winbindd_pam_auth_crap_send)
  [42677]: pam auth crap domain: [IPA.TEST] user: idmuser
[2020/11/11 09:23:53.283810,  3, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd_pam.c:409(find_auth_domain)
  Authentication for domain [IPA.TEST] refused as it is not a trusted domain
[2020/11/11 09:23:53.283825, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:810(process_request_done)
  process_request_done: [smbd(42677):PAM_AUTH_CRAP]: NT_STATUS_NO_SUCH_USER
[2020/11/11 09:23:53.283844, 10, pid=42663, effective(0, 0), real(0, 0), class=winbind] ../../source3/winbindd/winbindd.c:855(process_request_written)
  process_request_written: [smbd(42677):PAM_AUTH_CRAP]: delivered response to client

Signed-off-by: Alexander Bokovoy <ab@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
(cherry picked from commit 2a8b672652dcbcf55ec59be537773d76f0f14d0a)
---
 source3/auth/auth_sam.c | 45 +++++++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index 3c12f959faf..e8e0d543f8c 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -22,6 +22,7 @@
 
 #include "includes.h"
 #include "auth.h"
+#include "passdb.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -142,10 +143,28 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context,
 			break;
 		case ROLE_DOMAIN_PDC:
 		case ROLE_DOMAIN_BDC:
-			if ( !is_local_name && !is_my_domain ) {
-				DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n",
-					effective_domain));
-				return NT_STATUS_NOT_IMPLEMENTED;
+			if (!is_local_name && !is_my_domain) {
+			       /* If we are running on a DC that has PASSDB module with domain
+				* information, check if DNS forest name is matching the domain
+				* name. This is the case of FreeIPA domain controller when
+				* trusted AD DCs attempt to authenticate FreeIPA users using
+				* the forest root domain (which is the only domain in FreeIPA).
+				*/
+				struct pdb_domain_info *dom_info = NULL;
+
+				dom_info = pdb_get_domain_info(mem_ctx);
+				if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
+					is_my_domain = strequal(user_info->mapped.domain_name,
+								dom_info->dns_forest);
+				}
+
+				TALLOC_FREE(dom_info);
+				if (!is_my_domain) {
+					DEBUG(6,("check_samstrict_security: %s is not one "
+						 "of my local names or domain name (DC)\n",
+						 effective_domain));
+					return NT_STATUS_NOT_IMPLEMENTED;
+				}
 			}
 
 			break;
@@ -230,6 +249,24 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
 	}
 
 	is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
+	if (!is_my_domain) {
+	       /* If we are running on a DC that has PASSDB module with domain
+		* information, check if DNS forest name is matching the domain
+		* name. This is the case of FreeIPA domain controller when
+		* trusted AD DCs attempt to authenticate FreeIPA users using
+		* the forest root domain (which is the only domain in FreeIPA).
+		*/
+		struct pdb_domain_info *dom_info = NULL;
+		dom_info = pdb_get_domain_info(mem_ctx);
+
+		if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) {
+			is_my_domain = strequal(user_info->mapped.domain_name,
+						dom_info->dns_forest);
+		}
+
+		TALLOC_FREE(dom_info);
+	}
+
 	if (!is_my_domain) {
 		DBG_INFO("%s is not our domain name (DC for %s)\n",
 			 effective_domain, lp_workgroup());
-- 
2.29.2


From edd405a3918b5d52e7eeff2f8425478a0a1867ed Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Fri, 27 Nov 2020 11:22:15 +0100
Subject: [PATCH 104/104] docs-xml: Add a section about weak crypto in testparm
 manpage

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14583

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>

Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Fri Nov 27 13:48:20 UTC 2020 on sn-devel-184

(cherry picked from commit 5c27740aeff273bcd5f027d36874e56170234146)
---
 docs-xml/manpages/testparm.1.xml | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/docs-xml/manpages/testparm.1.xml b/docs-xml/manpages/testparm.1.xml
index 9099cda010f..7c7abf50e8b 100644
--- a/docs-xml/manpages/testparm.1.xml
+++ b/docs-xml/manpages/testparm.1.xml
@@ -171,6 +171,15 @@
 	errors and warnings if the file did not load. If the file was 
 	loaded OK, the program then dumps all known service details 
 	to stdout. </para>
+
+	<para>For certain use cases, SMB protocol requires use of
+	cryptographic algorithms which are known to be weak and already
+	broken. DES and ARCFOUR (RC4) ciphers and the SHA1 and MD5 hash
+	algorithms are considered weak but they are required for backward
+	compatibility. The testparm utility shows whether the Samba tools
+	will fall back to these weak crypto algorithms if it is not possible
+	to use strong cryptography by default.
+	In FIPS mode weak crypto cannot be enabled.</para>
 </refsect1>
 
 
-- 
2.29.2

